赛间出了5道,赛后通过各种途径又弄了2道,感觉干不动了,还有3道真心不想干了。
第一题,是个大水题,算出总长,在算出两点之间的正着走的长度,在总长捡它,输出小的即可。
第二题,就是给你好多个字符串,任务是找出最小的不是它们子串的字符串,你的字符串大小判断是这样的a,b,c........z,aa,ab,ac.......az,ba,bb,bc.......bz,ca,......zz,aaa,........,反正我差不多就当数字做了,模拟进位,用string里的find判断子串,然后就ok了
#include<iostream> #include<cstring> #include<cstdio> using namespace std; int n,num; string s[40],a; bool solve() { for(int i=0;i<n;i++) { if(s[i].find(a)!=-1)return false; } return true; } void add(int m,int jin) { if(jin==0)return; if(m>0) { if(a[m-1]!='z') { a[m-1]+=1; return; } else { a[m-1]='a'; add(m-1,1); } } else { a="a"+a; num++; } } void go() { while(1) { if(solve()) { cout<<a<<endl; return ; } add(num,1); } } int main() { scanf("%d",&n); for(int i=0;i<n;i++)cin>>s[i]; a="a"; num=1; go(); return 0; }
5 5 1 2 2 2 3 2 3 4 2 4 5 1 5第一行是代表5个人,5语言
第一个人会2语言,由于2在之前数据没人会(这里这是第一个数据),让r[2]=1;
第二个人会2,3语言,应为2语言第一个人会(r[2]=1)所以合并1,2俩人,f[2]=1了,3语言之前没人会,让r[3]=2;
。。。。。。(之后就这样依次类推)
最后只要看n个人分成了几摞就可以了,就是n个人f[x]=x的个数;
#include<iostream> #include<cstdio> #include<cstring> using namespace std; int m,n,num,yu,ans,sum; int f[105],r[105]; int find(int i) { if(f[i]==i)return i; else return find(f[i]); } void un(int a,int b) { int x=find(a); int y=find(b); f[x]=y; } int main() { while(scanf("%d%d",&n,&m)!=EOF) { sum=0; for(int i=1;i<=n;i++)f[i]=i; memset(r,0,sizeof(r)); for(int i=1;i<=n;i++) { scanf("%d",&num); if(num)sum=1; for(int j=0;j<num;j++) { scanf("%d",&yu); if(r[yu]==0)r[yu]=i; else un(i,r[yu]); } } if(sum==0) { cout<<n<<endl; continue; } ans=0; for(int i=1;i<=n;i++) { if(f[i]==i)ans++; } cout<<ans-1<<endl; } return 0; }
题目意思是要n个点,这n点只能构成最多m边凸边形,输出符合的n个点就可以,只要符合就可以,无固定答案。
一开始是搞圆,外圆上均匀去m点,内圆上均匀取剩下的点,开始时3点共线,改写了下,不共线了但答案错误。
借鉴了网上的方法,用的x正半轴方向二次函数,y=x^2上面取m点,y=-x^2去剩下的点,在让上面下面的点距离拉大,上面的+一个大数,下面-大数。神了
#include<iostream> #include<cstdio> #include<cmath> using namespace std; int main() { int m,n,a,b; scanf("%d%d",&n,&m); if(m==3&&n>4) { cout<<-1<<endl; } else { for(int i=1;i<=m;i++) { cout<<i<<" "<<1000000+i*i<<endl; } n-=m; for(int i=1;i<=n;i++) { cout<<i<<" "<<-1000000-i*i<<endl; } } return 0; }
第六题,水题,只要处理奇数次的就可以了,偶数次对结果不影响。
#include<iostream> #include<cstring> #include<cstdio> using namespace std; int main() { int a[5][5]; int b[5][5]; for(int i=1;i<=3;i++) { for(int j=1;j<=3;j++) { scanf("%d",&a[i][j]); b[i][j]=1; } } for(int i=1;i<=3;i++) { for(int j=1;j<=3;j++) { if(a[i][j]%2==1) { b[i][j]=-b[i][j]; b[i-1][j]=-b[i-1][j]; b[i+1][j]=-b[i+1][j]; b[i][j-1]=-b[i][j-1]; b[i][j+1]=-b[i][j+1]; } } } for(int i=1;i<=3;i++) { for(int j=1;j<=3;j++) { if(b[i][j]==1)cout<<1; else cout<<0; } cout<<endl; } return 0; }
#include<iostream> #include<cstdio> #include<cstring> using namespace std; int m,n; char a[55][55]; bool hen(int x1,int y1,int x2,int y2) { if(x1>x2) { for(int i=x1; i>=x2; i--) { if(a[i][y1]!='B')return false; } for(int i=y1; i<=y2; i++) { if(a[x2][i]!='B')return false; } } else { for(int i=x1; i<=x2; i++) { if(a[i][y1]!='B')return false; } for(int i=y1; i<=y2; i++) { if(a[x2][i]!='B')return false; } } return true; } bool shu(int x1,int y1,int x2,int y2) { for(int i=y1; i<=y2; i++) { if(a[x1][i]!='B')return false; } if(x1>x2) { for(int i=x1; i>=x2; i--) { if(a[i][y2]!='B')return false; } } else { for(int i=x1; i<=x2; i++) { if(a[i][y2]!='B')return false; } } return true; } bool go() { for(int i=0; i<m; i++) { for(int j=0; j<n; j++) { if(a[i][j]=='B') { for(int x=i; x<m; x++) { for(int y=0; y<n; y++) { if(a[x][y]=='B') { if(hen(i,j,x,y)||shu(i,j,x,y))continue; else return false; } } } } } } return true; } int main() { while(scanf("%d%d",&m,&n)!=EOF) { //getchar(); for(int i=0; i<m; i++) { scanf("%s",&a[i]); //scanf("%c",&a[i][j]); //getchar(); } if(go())cout<<"YES"<<endl; else cout<<"NO"<<endl; } return 0; }
意思是,给你n个数和k,要你从中取数,去了x就不能取x*k,问做多能取几个。思路先排序,然后从头到尾遍历,第一个肯定取,将第一个数k倍的标记代表不能取它了,然后以后的数先判断是否被标记了,被标记则跳过,没被标记则取,并标记它的k倍,就ok了。
#include<iostream> #include<cstdio> #include<map> #include<algorithm> long long int a[100005]; using namespace std; int main() { int n,k,ans; while(scanf("%d%d",&n,&k)!=EOF){ map<long long int,int >p; ans=0; for(int i=0;i<n;i++) { scanf("%d",&a[i]); } sort(a,a+n); for(int i=0;i<n;i++) { if(p[a[i]]==0) { ans++; p[k*a[i]]=1; } } cout<<ans<<endl;} return 0; }
第十题,。。。