卑微小蒟蒻在线被吊打

模拟赛总结

第一题美食街

1.美食街 (street.cpp) 【问题描述】 水宝宝的美食街开始营业喽 美食街八大菜肴:烤绿鸟(主食),拔丝 QAQ 套餐(副食),红烧 KMP(主菜), Treap 刺身(副菜),油炸内存条(小吃),奶油 CPU(甜品),SPFA 奶盖(饮品),冰镇 机油(饮品) 水宝宝美食街开张第二天,wza 神犇来到水宝宝美食街,却被琳琅满目的食品吓住 了,他急需知道水宝宝的美食街有没有他想吃的东西 给出 n 个食物编号,然后有 m 个询问,每个询问一个整数,询问该整数是否在 n 个食物 编号中出现过,保证编号为正整数

【输入格式】 输入文件名为 street.in。 第一行:n 第二行:m 第三行:n 个询问的编号 第四行:m 个询问的编号

【输出格式】 输出文件名为 street.out。 一共 m 行,若出现则输出”YES”,否则输出”NO”

【说明】 对于 30%的数据,1<=n,m<=1000 对于 60%的数据,1<=n,m<=10000 对于 100%的数据,1<=n,m<=200000 所有数据<=1e17

一看到所有数据小于1e17,就明白了,桶装不下。所以为了节约时间,就把目光投向了二分。其实就是一个二分模版题啦,接下来,放代码(注意,这题如果时间卡1秒,就要加快读呢)

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int n,m;
 4 unsigned long long a[200009],x,lc=100000000000000002,rc,mid;
 5 inline ll read(){
 6     ll x=0,f=1;
 7     char ch=getchar();
 8     while(ch<'0'|| ch>'9'){ if(ch=='-') f=-1;ch=getchar();}
 9     while(ch>='0'&& ch<='9'){ x=x*10+ch-'0';ch=getchar();}
10     return x*f;
11 }
12 int main(){
13 //    freopen("street.in","r",stdin);
14 //    freopen("street.out","w",stdout);
15     n=read();m=read();
16     for(int i=1;i<=n;i++){
17         a[i]=read();
18         lc=min(lc,a[i]);
19         rc=max(rc,a[i]);
20     }
21     sort(a+1,a+n+1);
22     for(int i=1;i<=m;i++){
23         x=read();
24         if(x<lc||x>rc) cout<<"NO"<<endl;
25         else{
26             int l=1,r=n;
27             while(1){
28                 if(l==r){
29                     if(a[l]==x) cout<<"YES"<<endl;
30                     else cout<<"NO"<<endl;
31                     break;
32                 }
33                 mid=(l+r)>>1;
34                 if(a[mid]<x) l=mid+1;
35                 else r=mid;
36             }
37         }
38     }
39     return 0;
40 }

第二题采访

2. 采访 (interview.cpp) 【问题描述】 有 n 个人站成一排,水宝宝要采访其中一些人“你幸福吗?”。但是相邻两个人不 能都被采访,否则这两个人就会因为相互影响而说出不真实的回答。shui 想知道一共有 多少种满足条件的采访方法呢?(可以不选)

【输入格式】 输入文件名为 interview.in。 一行一个 n。

【输出格式】 输出文件名为 interview.out。 一行表示答案。

【说明】 对于 30%的数据,1<=n<=10 对于 60%的数据,1<=n<=100 对于 100%的数据,1<=n<=1000

分析一下问题,显而易见,这是斐波那契数列呢2 3 5 8 13。。。但是请观察它的数据范围,小于等于1000,说明如果只是用unsigned long long会爆掉,所以这是斐波那契+高精加法,很容易代码实现

 1 #include <bits/stdc++.h>
 2 using namespace std;  
 3 #define ll long long
 4 const int power = 9;
 5 const int base = pow(10,power);
 6 const int MAXL = 30001;
 7 char a[MAXL],b[MAXL];
 8 struct node{
 9     ll a[MAXL];
10     int part;
11     node(){    memset(a,0,sizeof(a));} 
12     node(string s){
13         memset(a,0,sizeof(a));
14         int len=s.size();
15         part=(len-1+power)/power;
16         for(int i=len-1,k=0,t=0,w;i>=0;w*=10,i--,k++){
17             if(k%power==0){ w=1,t++;}
18             a[t]+=w*(s[i]-'0');
19         }    
20     } 
21     void re() { reverse(a+1, a+part+1); }      
22     void add(int r){if(r||part) a[++part]=r;} 
23     void print(){
24         printf("%d",a[part]);
25         for(int i=part-1;i>0;i--) printf("%0*d",power,a[i]);    
26     } 
27 }p,q,ans;
28 node operator + (const node &p,const node &q){
29     node c;
30     c.part=max(p.part,q.part);
31     for(int i=1;i<=c.part;i++){
32         c.a[i]=c.a[i]+p.a[i]+q.a[i];
33         c.a[i+1]+=c.a[i]/base;
34         c.a[i] %=base; 
35     } 
36     if(c.a[c.part+1]) ++c.part;
37     return c; 
38 } 
39 int main(){
40 //    freopen("interview.in","r",stdin); 
41 //    freopen("interview.out","w",stdout);
42     int n;
43     cin>>n;
44     string a,b;a="2",b="3";
45     if(n==1){cout<<a;return 0;}
46     if(n==2){cout<<b;return 0;}
47     p=node(a),q=node(b);
48     for(int i=1;i<=n-2;i++){
49         ans=p+q;
50         p=q;q=ans;
51     }
52     ans.print();
53     return 0;    
54 }  

第三题值周

【问题描述】 JC 内长度为 L 的马路上有一些值周同学,每两个相邻的同学之间的间隔都是 1 米。 我们可以把马路看成一个数轴,马路的一端在数轴 0 的位置,另一端在 L 的位置; 数轴上的每个整数点,即 0,1,2,…L,都有一个值周同学。 由于水宝宝有用一些区间来和 ssy 搞事情,所以为了避免这种事走漏风声,水宝宝要踹 走一些区域的人。这些区域用它们在数轴上的起始点和终止点表示。 已知任一区域的起始点和终止点的坐标都是整数,区域之间可能有重合的部分。现在要 把这些区域中的人(包括区域端点处的两个人)赶走。 你的任务是计算将这些人都赶走后,马路上还有多少个人

【输入格式】 输入文件名为 move.in。 第一行有 2 个整数 L 和 M,L 代表马路的长度,M 代表区域的数目,L 和 M 之间用一个空 格隔开。 接下来的 M 行每行包含 2 个不同的整数,用一个空格隔开,表示一个区域的起始点和终 止点的坐标

【输出格式】 输出文件名为 move.out。 1 个整数,表示马路上剩余的人的数目。

【数据规模与约定】 对于所有的数据,1≤L≤100000000 对于 30%的数据,1<=M<=100 对于 60%的数据,1<=M<=1000 对于 100%的数据,1<=M<=100000

这道题我也不知道我当时怎么想的,就打了个暴力,结果爆了个零。。。

然后改的时候我感觉排序可以,差分也可以

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int l,n,k,tot;
 4 struct node{
 5     int e,b;
 6 }a[100009],ans[100009];
 7 bool cmp(node x,node y){
 8     return x.b>y.b;
 9 }
10 int main(){
11 //    freopen("move.in","r",stdin);
12 //    freopen("move.out","w",stdout);
13     cin>>l>>n;
14     for(int i=1;i<=n;i++){
15         cin>>a[i].b>>a[i].e;
16     }
17     sort(a+1,a+1+n,cmp);
18     k++;
19     ans[k].e=a[1].e;
20     ans[k].b=a[1].b;
21     for(int i=1;i<=n;i++){
22         if(a[i].e>ans[k].b){
23             if(a[i].b<ans[k].b) ans[k].b=a[i].b;
24         }
25         else{
26             k++;
27             ans[k].e=a[i].e;
28             ans[k].b=a[i].b;
29         }
30     }
31     for(int i=1;i<=k;i++){
32         tot+=ans[i].e-ans[i].b+1;
33     }
34     cout<<l-tot+1;
35     return 0;
36 }
37 //500 3
38 //150 300
39 //100 200
40 //470 471

 

第四题吃西瓜

【问题描述】 没事就来吃个西瓜? 水宝宝是一个不争气的宝宝,所以口水流了下来…… 吃西瓜当然要切啦,水宝宝每 刀都是笔直地切下去,并且在切完后才会把一块块的西瓜分开。 那么:将西瓜切 n 刀最多能切成几块呢? 答案可能有点大,请对 10^9+7 取模。 【输入格式】 输入文件名为 watermelon.in。 多组数据,第一行一个 T 表示数据组数 接下来 T 行,每行一个数 n,表示要把西瓜切 n 刀 【输出格式】 输出文件名为 watermelon.out。 T 行,每行一个数对应把西瓜切 n 刀的答案【数据规模与约定】 对于 10% 的数据,满足 n≤5。 对于 50% 的数据,满足 n≤10000。 对于 100% 的数据,满足 n≤10^9,T≤100。

这明明就是个神奇的小学数学题嘛!!!那你考这个就是想虐我是吧 哼 

很显然,切的刀数与切出来的块数的联系是一个三次方程,(毕竟是个三维空间),切一刀2,切两刀4,切三刀8,切四刀15(我就是这里模拟错了,当时是真没想到它怎样用四刀切出15块)解方程ing 嘿嘿

 

算出来是n3+5*n呢,所以找出规律后的代码就是有手就行


 

期待(星星眼)鬼知道我在期待着啥

版权声明:本文为001A原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/001A/p/13875155.html