A. Sushi for Two
分析
模拟题,只需要模拟找出连续最长的111222或222111这种数段即可.
代码
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #include <cstdio> 2 #include <cmath> 3 #include <iostream> 4 #include <cstring> 5 #include <algorithm> 6 #include <vector> 7 #include <string> 8 #include <utility> 9 #include <queue> 10 #include <stack> 11 #include <map> 12 const int INF=0x3f3f3f3f; 13 using namespace std; 14 15 int s[100000]; 16 17 int main() 18 { 19 int n; 20 cin>>n; 21 for(int i=0;i<n;i++) scanf("%d",&s[i]); 22 int k=0; 23 int ans=0,a=0,b=0; 24 while(k<n) 25 { 26 while(s[k]==1&&k<n) a++,k++; 27 if(a<=b) ans=max(ans,2*a); 28 else ans=max(ans,2*b); 29 b=0; 30 while(s[k]==2&&k<n) b++,k++; 31 if(b<=a) ans=max(ans,2*b); 32 else ans=max(ans,2*a); 33 a=0; 34 } 35 cout<<ans<<endl; 36 return 0; 37 }
B. Circus
分析
这题需要找出题目中的数学关系,先把人分成4种(0,0)(1,0)(0,1)(1,1),人数分别为a0,b0,c0,d0,总人数为n,假设第一场4种人分别选了a,b,c,d个,依题意有a+b+c+d=n/2,b+d=c0-c+d0-d,这个方程组有两个方程4个变量,即有两个未知量,分别枚举其中两个未知量,来确定另外两个未知量,只要保证算出来的a,b,c,d合法即可.(下面代码思路相同不过设置的变量不同,仅供参考)
代码
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #include <cstdio> 2 #include <cmath> 3 #include <iostream> 4 #include <cstring> 5 #include <algorithm> 6 #include <vector> 7 #include <string> 8 #include <utility> 9 #include <queue> 10 #include <stack> 11 #include <map> 12 const int INF=0x3f3f3f3f; 13 using namespace std; 14 15 int a[5000],b[5000],c[5000],d[5000]; 16 char fir[5000],sec[5000]; 17 18 int main() 19 { 20 int na=0,nb=0,nc=0,nd=0; 21 int n; 22 cin>>n; 23 getchar(); 24 for(int i=0;i<n;i++) scanf("%c",&fir[i]); 25 getchar(); 26 for(int i=0;i<n;i++) 27 { 28 scanf("%c",&sec[i]); 29 if(fir[i]=='0'&&sec[i]=='0') a[na++]=i+1; 30 if(fir[i]=='0'&&sec[i]=='1') b[nb++]=i+1; 31 if(fir[i]=='1'&&sec[i]=='0') c[nc++]=i+1; 32 if(fir[i]=='1'&&sec[i]=='1') d[nd++]=i+1; 33 } 34 35 int i=-1,j=-1,k=-1,l=-1; 36 for(i=0;i<=na;i++) 37 { 38 int s=0; 39 for(j=0;j<=nb;j++) 40 { 41 k=n-2*i-nb-nd-j; 42 l=nb+nd-n/2+i; 43 if(nc>=k&&k>=0&&l>=0&&nd>=l) 44 { 45 s=1; 46 break; 47 } 48 } 49 if(s) break; 50 } 51 52 if(i<=na&&j<=nb) 53 { 54 for(int q=0;q<i;q++) cout<<a[q]<<' '; 55 for(int q=0;q<j;q++) cout<<b[q]<<' '; 56 for(int q=0;q<k;q++) cout<<c[q]<<' '; 57 for(int q=0;q<l;q++) cout<<d[q]<<' '; 58 cout<<endl; 59 } 60 else cout<<-1<<endl; 61 return 0; 62 }
C. Skyscrapers
分析
这道题读懂题意后最关键的是离散化操作,这个操作会了码一下细节基本就过了.
代码
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #include <cstdio> 2 #include <cmath> 3 #include <iostream> 4 #include <cstring> 5 #include <algorithm> 6 #include <vector> 7 #include <string> 8 #include <utility> 9 #include <queue> 10 #include <stack> 11 #include <map> 12 #include <set> 13 const int INF=0x3f3f3f3f; 14 using namespace std; 15 16 typedef pair<int,int> P; 17 int row[1000][1000]; 18 int r[1000]; 19 int column[1000][1000]; 20 int c[1000]; 21 int mapp[1000][1000]; 22 vector<int> v; 23 24 int main() 25 { 26 int n,m; 27 cin>>n>>m; 28 for(int i=0;i<n;i++) 29 for(int j=0;j<m;j++) 30 scanf("%d",&mapp[i][j]); 31 for(int i=0;i<n;i++) 32 { 33 34 for(int j=0;j<m;j++) v.push_back(mapp[i][j]); 35 sort(v.begin(),v.end()); 36 vector<int>::iterator e=unique(v.begin(),v.end()); 37 r[i]=e-v.begin(); 38 for(int j=0;j<m;j++) row[i][j]=lower_bound(v.begin(),e,mapp[i][j])-v.begin()+1; 39 v.clear(); 40 } 41 for(int j=0;j<m;j++) 42 { 43 44 for(int i=0;i<n;i++) v.push_back(mapp[i][j]); 45 sort(v.begin(),v.end()); 46 vector<int>::iterator e=unique(v.begin(),v.end()); 47 c[j]=e-v.begin(); 48 for(int i=0;i<n;i++) column[i][j]=lower_bound(v.begin(),e,mapp[i][j])-v.begin()+1; 49 v.clear(); 50 } 51 52 /* for(int i=0;i<n;i++) 53 { 54 for(int j=0;j<m;j++) 55 printf("r=%d,c=%d ",row[i][j],column[i][j]); 56 cout<<endl; 57 } 58 for(int i=0;i<n;i++) printf("r[%d]=%d\n",i,r[i]); 59 for(int j=0;j<m;j++) printf("c[%d]=%d\n",j,c[j]); 60 */ 61 for(int i=0;i<n;i++) 62 { 63 for(int j=0;j<m;j++) 64 { 65 int a=row[i][j],b=column[i][j],ans=INF; 66 if(a>=b) ans=max(r[i],c[j]+a-b); 67 else ans=max(r[i]+b-a,c[j]); 68 cout<<ans<<' '; 69 } 70 cout<<endl; 71 } 72 return 0; 73 }
D. Camp Schedule
分析
套kmp算法的题,只需要把第一个字符串拆成1和0,再求出第二个字符串的最小循环节,然后不断按最小循环节顺序输出1,0直到拆分的1或0不够用为止,再把剩下的0或1输出完即可.
代码
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #include <cstdio> 2 #include <cmath> 3 #include <cstring> 4 #include <iostream> 5 #include <algorithm> 6 #include <utility> 7 #include <vector> 8 #include <string> 9 #include <queue> 10 #include <stack> 11 #include <map> 12 const int INF=0x3f3f3f3f; 13 using namespace std; 14 15 char a[600000]; 16 int b[600000]; 17 18 void kmp(int cnt) 19 { 20 int i=0; 21 int k=-1; 22 b[0]=-1; 23 while(i<cnt) 24 { 25 26 if(k==-1||a[i]==a[k]) 27 { 28 if(a[++i]==a[++k]) b[i]=b[k]; 29 else b[i]=k; 30 } 31 else k=b[k]; 32 } 33 return ; 34 } 35 36 int main() 37 { 38 char x; 39 //��ֵ�һ������ 40 int a0=0,a1=0; 41 while(scanf("%c",&x)&&x!='\n') 42 { 43 if(x=='0') a0++; 44 else a1++; 45 } 46 47 int k=0; 48 while(scanf("%c",&x)&&x!='\n') a[k++]=x; 49 kmp(k); 50 int l=k-b[k]; 51 52 53 //����Сѭ���ڲ��Ϲ�������,ֱ����һ�����е�0��1������,�ٰ�ʣ�µ�0��1ȫ��������� 54 int s=0; 55 while(1) 56 { 57 if(s) break; 58 for(int i=0;i<l;i++) 59 { 60 if(a[i]=='0'&&a0) printf("0"),a0--; 61 else if(a[i]=='1'&&a1) printf("1"),a1--; 62 else 63 { 64 s=1; 65 break; 66 } 67 } 68 } 69 if(a0) 70 { 71 for(int i=0;i<a0;i++) printf("0"); 72 cout<<endl; 73 } 74 else if(a1) 75 { 76 for(int i=0;i<a1;i++) printf("1"); 77 cout<<endl; 78 } 79 else cout<<endl; 80 return 0; 81 }