神秘代码:什么是密码
A:https://codeforces.com/problemset/problem/761/A
题意:给你一个从1到正无穷的序列,给你a,b(0 ≤ a, b ≤ 100) ,要你输出在序列中是否有存在一段不为0的区间使得里面包含a个奇数和b个偶数。
思路:很容易想到,对于任何一个区间,里面的奇数和偶数的数量的差值最大为1。但是注意,由于区间不为零,那么当a==b==0的时候,虽然差值为0,但是题目告诉我们不存在为0的区间,需要特判掉。至此代码也就可以写出来。
//author CN.TTDragon #include<bits/stdc++.h> typedef long long ll; const ll mod=1e9+7; const ll maxn=1e5+7; const double pi=acos(-1); using namespace std; int main() { int a,b; cin>>a>>b; if(a==0&&b==0) { cout<<"NO"<<endl; return 0; } int t=a-b; t=abs(t); //cout<<t<<endl; if(abs(a-b)<=1) { cout<<"YES"<<endl; } else { cout<<"NO"<<endl; } return 0; }
B:https://codeforces.com/problemset/problem/570/B
题意:两个人在做取游戏,数字总数是n,其中一个人取了m,游戏的胜利是两人各取一个数,再从n个数中随机取一个,这个随机数离谁取的数字近,谁就赢。在已知n,m的情况下,要你输出另一个人取那个数才能使得胜利几率最大。
思路:一开始可以很容易的想到这个数一定是m-1或者m+1,这样就可以完全占据它的左/右的所有数字。接下来又会发现,这个平均分段是要看n的。当n为奇数时,有一个数是十分特殊的,那就是(n+1)/2。再细看,题目说了,当有多个答案时,输出小的那一个。但是有一个特殊的奇数1,因为不能取0的缘故,只能特判掉。至此代码也就可以写出来了。
//author CN.TTDragon #include<bits/stdc++.h> typedef long long ll; const ll mod=1e9+7; const ll maxn=1e5+7; const double pi=acos(-1); using namespace std; int main() { ll n,m,t; while(cin>>n>>m) { if(n==1) { cout<<1<<endl; continue; } t=(n+1)/2; if(n&1)//n是奇数 { if(m>t) { cout<<m-1<<endl; } else if(m<t) { cout<<m+1<<endl; } else if(m==t) { cout<<m-1<<endl; } } else { if(m<=t) { cout<<m+1<<endl; } else { cout<<m-1<<endl; } } } return 0; }
C:https://vjudge.net/problem/UVA-11489
题意:就说两个人又在玩游戏,游戏规则是给你一个数组里面全是1-9的数字,每次可以删除数组中一个元素,要求删除后剩余元素的和能够被3整除。
思路:对于本题,1-9可以按照它们除3后的余数分为三类(不妨设置为0,1,2),这样一来题目就被简化了。那么每次我们都判断一下当前的sum%3,然后去看一下此时的数组中是否还有这个余数,有就减去,没有的话就说明此时操作不了了。至此代码也就写出来了。
//author CN.TTDragon #include<bits/stdc++.h> typedef long long ll; const ll mod=1e9+7; const ll maxn=1e5+7; const double pi=acos(-1); using namespace std; char a[1005]={0}; int tong[4]={0}; int sum=0; int len; int num=0; int t; int cnt; int main() { scanf("%d",&t); for(num=1;num<=t;num++) { sum=0; cnt=0; memset(a,0,sizeof(a)); for(int i=0;i<4;i++) { tong[i]=0; } scanf("%s",a); len=strlen(a); for(int i=0;i<len;i++)//分类 { if(int(a[i])%3==0) { tong[3]++; sum+=3; } else if(int(a[i])%3==1) { tong[1]++; sum+=1; } else { tong[2]++; sum+=2; } } while(sum)//如果sum是0,那么说明数组空了,刚刚取数的人是胜者 { if(sum%3==0&&tong[3]>0) { tong[3]--; cnt++; sum-=3; } else if(sum%3==1&&tong[1]>0) { tong[1]--; cnt++; sum-=1; } else if(sum%3==2&&tong[2]>0) { tong[2]--; cnt++; sum-=2; } else { break; } } if(cnt&1) { printf("Case %d: S\n",num); } else { printf("Case %d: T\n",num); } } return 0; }
D:https://codeforces.com/problemset/problem/996/B
题意:有n个队伍,一个人在排队,但是他有一个奇怪的排队习惯,他最开始站在第一个队伍的末尾,如果此时他不是队伍的头,那么他就会去下一个队伍。注意,当在最后一个队伍时,会返回第一个队伍。要求输出他是从哪个队伍进入会场的。
思路:最开始也是暴力,那么就是从第一个队伍开始循环遍历,对于每个队伍,用总人数减去时间,如果小于等于0则说明此时是队伍的头,那么这个队伍编号就是答案。那么这样做,最坏复杂度是O(max( ))结合数据范围我们知道,这个必然会T,那么我们再想,因为它要我们输出进入的队伍编号,那么我们能不能想一下对于每个队伍,如果此人非要从这个队伍进去,那么所消耗的时间是多少。这么一来,我们只需要找到最小值所对应的队伍就好(有多个的时候输出编号最小的那个)。那么这个时间怎么算了,细想一下,这个人到每个队伍的时间是一定的,设队伍编号是t,第1秒时在1号队伍,那么到达t的时间一定是,t,t+n,t+2*n 那么他从这个队伍进去时此队伍必然是已经没人了的(如果哪怕还有一个人,他都不会是队伍的头)。还有一点点小细节(语文不行,真的写不出来,看一下代码理解一下吧~/菜哭),至此代码就写出来了。
//author CN.TTDragon #include<bits/stdc++.h> typedef long long ll; const ll mod=1e9+7; const ll maxn=1e5+7; const double pi=acos(-1); using namespace std; ll a[maxn]={0};//队伍人数 ll b[maxn]={0};//对应的时间 int main() { ll n; cin>>n; ll mi=1e11; ll place=0;//记录从那个位置进,也就是答案 for(int i=0;i<n;i++) { cin>>a[i]; a[i]-=i;//在第一次到达这个队伍时,已经有i个人进去了 if(a[i]<=0&&place==0)//如果第一次到达就已经是一个空的队伍了。答案也就出来了 { place=i+1; } else { if(a[i]%n==0)//能够整除时,到达那里恰是0人 { b[i]=(a[i]/n)*n+i+1; } else//不能整除,要再转一轮 { b[i]=((a[i]/n)+1)*n+i+1; } } } if(place!=0) { cout<<place<<endl; return 0; } for(int i=0;i<n;i++) { if(b[i]<mi) { mi=b[i]; place=i+1; } } cout<<place<<endl; return 0; }
E:https://codeforces.com/problemset/problem/454/C
题意:给你一个m面的骰子,让你投n次,取n次的最大值,问你最大期望是多少。
思路:对于最大值m,如果我们不想m出现,那么我们就是在(m-1)个数中让它们出现n次,即 ,而总排列数是 ,那么不含m的情况就是,那么对于m,它能带来的期望就是 。那么这样就写完了,但是我们看一下数据范围,1e5。必定会溢出。这里就有一个优化(其实是化简),用(pow(i/m,n)-pow((i-1)/m,n))来代替后面m后面的部分。至此代码也出来了。
//author CN.TTDragon #include<bits/stdc++.h> typedef long long ll; const ll mod=1e9+7; const ll maxn=1e5+7; const double pi=acos(-1); using namespace std; int main() { ios::sync_with_stdio(false); ll m,n; cin>>m>>n; double tot=0; for(double i=1;i<=m;i++) { tot+=i*(pow(i/m,n)-pow((i-1)/m,n)); } cout<<fixed<<setprecision(12)<<tot<<endl; return 0; }
F:https://zoj.pintia.cn/problem-sets/91827364500/problems/91827370133
题意:给你一个大圆半径为R,给你一个小圆半径为r。在大圆(圆心在原点)里面有n个建筑物,每个建筑物都有一个坐标(x,y),这个小圆(记作o1)它一定完全包含在大圆里面(最坏情况就是两圆内切)。让你求那些点落在小圆里面的几率最大,如果有多个的话,从小到大输出出来。
这题本意就是游戏大逃杀里面的缩圈。问你在哪些点更容易刷出天命圈而已(我明明没有玩过,但怎么这么熟练啊 ~ )
思路:一开始会很容易想到就是对每个建筑物都画一个半径为r的圆(记为o2),圆心在o2中的圆都可以使得那个建筑物成为天选之地。但是由于题目要求,它要小圆完全包含在大圆中。那么o1的圆心到原点的距离就应该小于R-r。这样才能完全包含在大圆中。小圆o1的圆心可取范围就会缩水。
但是如果所有的建筑物的小圆o1的范围都不是完全体,那么问题就变成找离原点最近的点了(你可以好好想想),因为每个建筑物的o1范围都不是完全体,那么肯定是越靠近原点,可取范围越大。
到这里就完了?不是的,还有一种特殊情况,那就是r==R的时候,所有的建筑物都是一样的概率(只有原点可取)。这时候要全部输出出来。至此代码也就写出来了。
注意一下,我们取距离的时候肯定是sqrt的,但是由于精度问题,在这题会被卡。于是我们要用整数来处理掉。
//author CN.TTDragon #include<bits/stdc++.h> typedef long long ll; const ll mod=1e9+7; const ll maxn=1e5+7; const double pi=acos(-1); using namespace std; ll a[105]={0}; ll n,R,r,x,y; ll ff=0; ll ans[105]={0}; ll mi=1e9+7; int main() { int t ; cin>>t; while(t--) { cin>>n>>R>>r; memset(a,0,sizeof(a)); memset(ans,0,sizeof(ans)); ff=0; mi=0x3f3f3f3f; int m=0; for(int i=0;i<n;i++) { cin>>x>>y; a[i]=pow(x,2)+pow(y,2);//用整数来代替sqrt mi=min(mi,a[i]);//没有符合完美条件的时候用! } if(R==r)//特殊情况 { cout<<n<<endl;//这里一开始没输出n,改到吐血! for(int i=0;i<n-1;i++) { cout<<i+1<<" "; } cout<<n<<endl; continue; } for(int i=0;i<n;i++) { //cout<<a[i]<<" "<<R*R+4*r*r-4*R*r<<endl; if(a[i]<=R*R+4*r*r-4*R*r)//存在完美符合条件的点 { ans[ff]=i+1; ff++; } } if(ff) { cout<<ff<<endl; for(int i=0;i<ff-1;i++) { cout<<ans[i]<<" "; } cout<<ans[ff-1]<<endl; } else//没有完美符合条件的点,找最小的 { for(int i=0;i<n;i++) { if(a[i]==mi) { ans[m]=i+1; m++; } } cout<<m<<endl; for(int i=0;i<m-1;i++) { cout<<ans[i]<<" "; } cout<<ans[m-1]<<endl; } } }
G:https://codeforces.com/problemset/problem/1101/C
H:https://codeforces.com/problemset/problem/412/D
写在最后:
在比赛的时候,是真的慌,没有好好看数据范围,A题wa傻了,B题1没拿出来特别处理,写了个奇怪的东西把test17过了,然后就一直wa18,到结束也没写出来。结果给这两个签到题耽搁了2个小时,结果E都没开。最后变成了全校最菜(拖了两位队友大爹的后腿!)。直接自闭。
之所以写是因为自己连CF的AB题都不会写,希望自己能从中吸取教训,日后能把边界和特殊情况处理好。引以为戒!
之所以比赛编号是-1是因为学长说先来两场体验一下。
后续应该会把EFG补上,H的话,估计不太可能。
E题已补,挺巧妙的(其实是自己脑子姜化~)(故意玩梗)
F题已补,超级痛苦,一开始想的是只画一个r的圆,然后符合条件记成1,到时在输出,没想到是在那个r的圆中再画一个圆。WA了好几发,后面度娘才会的( 原帖 ),这篇题解到此就结束了,感谢你的观看,希望对你有帮助(其实是对我自己有帮助),至于那个G题,看缘分吧。
溜溜球,我现在只想去帮露娜sama改设计图。