http://codeforces.com/gym/101196/attachments
A题
B题
题意:一群人玩桌上足球(>4人),分成黑白两队,每队有进攻和防守两名玩家,如果有一方失败则失败方的防守坐到等候席的结尾、进攻被流放到防守区再上来一个人作为进攻方。而胜利方则是攻防对换。问上场时间最长的有哪些队伍?打印队伍的最初状态的姓名(先打印进攻方后打印防守方)。
思路:首先把所有玩家放入队列中,然后求出在场上时间最长的队伍是在第几轮比赛时入场的放入数组中。然后依次模拟比赛,当模拟到数组中的轮数时就打印此时的队伍状态。
1 #include2 #include 3 #include<string> 4 using namespace std; 5 string p[12],s,ss; 6 queue<string>que; 7 string now[2][2]; 8 int a[1005]; 9 int main() 10 { 11 int n; 12 while(cin>>n) 13 { 14 while(!que.empty()) 15 que.pop(); 16 for(int i=1; i<=n; i++) 17 { 18 cin>>s; 19 que.push(s); 20 } 21 cin>>s; 22 int len=s.length(); 23 int maxn=0; 24 int t=0; 25 for(int i=0; i<len;) 26 { 27 int k=i+1,num=0; 28 while(s[k]==s[i]) 29 { 30 num++; 31 k++; 32 } 33 if(maxn<num) 34 { 35 maxn=num; 36 t=0; 37 a[t++]=i; 38 } 39 else if(maxn==num) 40 { 41 a[t++]=i; 42 } 43 i=k; 44 } 45 int p=t; 46 for(int i=0; i<2; i++) 47 for(int j=0; j<2; j++) 48 { 49 now[j][i]=que.front(); 50 que.pop(); 51 } 52 t=0; 53 for(int i=0; i ) 54 { 55 //cout< 56 //cout< ][1]<<" "<57 if(s[i]=='W') 58 { 59 ss=now[0][0]; 60 now[0][0]=now[0][1]; 61 now[0][1]=ss; 62 que.push(now[1][1]); 63 now[1][1]=now[1][0]; 64 now[1][0]=que.front(); 65 que.pop(); 66 } 67 else if(s[i]=='B') 68 { 69 ss=now[1][0]; 70 now[1][0]=now[1][1]; 71 now[1][1]=ss; 72 que.push(now[0][1]); 73 now[0][1]=now[0][0]; 74 now[0][0]=que.front(); 75 //cout< ][0]<<endl; 85 } 86 else 87 { 88 cout<76 que.pop(); 77 } 78 if(i==a[t]&&t<p) 79 { 80 if(i==0) 81 { 82 if(s[i]=='W') 83 { 84 cout< ][1]<<" "<0 0 1 1][0]<<endl; 89 } 90 t++; 91 } 92 else 93 { 94 if(s[i]=='W') 95 { 96 cout< 0][0]<<" "< 0][1]<<endl; 97 } 98 else 99 { 100 cout< 1][0]<<" "< 1][1]<<endl; 101 } 102 t++; 103 } 104 } 105 } 106 107 } 108 return 0; 109 }
C题
题意:给你两组字符串,一组是加密之后的字符串,一组是加密的前len个密文,从len+1开始密文为原文从第一个,len+2的密文为原文第二个,以此类推,问原文是什么?
思路:前len个原文字符是(s[i]-key[i]+26)%26,后面的是(s[i]-ans[i-len]+26)%26,跑一遍就能得到结果ans了
1 #include2 #include 3 #include 4 using namespace std; 5 char ch[1005],ans[1005],tmp[1005]; 6 7 int main() 8 { 9 10 while(scanf("%s",ch)!=-1) 11 { 12 scanf("%s",tmp); 13 int len1=strlen(ch); 14 int len2=strlen(tmp); 15 for(int i=0;i ) 16 { 17 ans[i]=(ch[i]-tmp[i]+26)%26+'A'; 18 } 19 for(int i=len2;i ) 20 { 21 ans[i]=(ch[i]-ans[i-len2]+26)%26+'A'; 22 } 23 ans[len1]='\0'; 24 printf("%s\n",ans); 25 26 } 27 return 0; 28 }
D题
E题
题意:问一个字符串多个相同的子串组成,将相同子串变成一个单字符M,变完之后的字符串长度加上子串的长度的最小值是多少?
思路:由于所给字符串较短,直接暴力求解。求长度为从1~len/2的所有子串,然后依次于主串进行匹配,更新的最小结果即可。
1 #include2 #include 3 #include<string> 4 using namespace std; 5 string s; 6 string c[105][105]; 7 map<string,int > mp; 8 int main() 9 { 10 while(cin>>s) 11 { 12 int len=s.size(); 13 int ans=len; 14 for(int i=1; i ) 15 { 16 for(int j=0; j ) 17 { 18 string ch=s.substr(j,i); 19 int tmp=0; 20 for(int k=0;k<=len-i;) 21 { 22 string p=s.substr(k,i); 23 if(p==ch) 24 { 25 tmp++; 26 k=k+i; 27 } 28 else 29 k++; 30 } 31 if(ans>len-tmp*(ch.size()-1)+ch.size()) 32 ans=len-tmp*(ch.size()-1)+ch.size(); 33 } 34 } 35 cout< endl; 36 } 37 return 0; 38 }
F题
G题
H题
题意:给两个凸多边形的边界,问这两个凸多边形有多少个点只包含在A内部,又有多少个点包含在B的内部,还有多少个点包含在A和B的内部(不含边界点)。
思路:从A点开始进行搜索边界,并在标记数组vis1中进行记录,同理对B进行处理记录在vis2中,然后对vis1和vis2的外围进行标记覆盖,最后取得图上的字符是点的vis1或vis2为0的结果。
1 #include2 #include 3 #include 4 #include 5 #include 6 #include 7 #include 8 #include <string> 9 #include <set> 10 #include 11 #include
I题
J题