2018 CCPC 桂林站(upc复现赛)补题
J.石头游戏 (博弈)
Alice和Bob总是在玩游戏!今天的比赛是关于从石堆中依次取出石头。
有n堆石头,第i堆包含A [i]个石头。
由于每个堆中的宝石数量与其邻居的宝石数量不同,因此他们决定在不打破该属性的情况下从其中一个中取出一块石头。Alice先拿。
规定当谁不能拿石头将输掉比赛。
现在给出一个数字N和N个数字代表每堆石子的个数,你要确定最后的获胜者,假设他们都足够聪明。
Ps: 你应该注意到即使是一堆0石头仍然被视为一堆!
第一次看题时没有看到每次限取一颗,后来发现时比赛已经快结束了orz。读错题坑了队友。
1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<cmath> 5 using namespace std; 6 const int maxn=1e5+10; 7 int num[maxn],a[maxn]; 8 9 int main() 10 { 11 int t,n; 12 scanf("%d",&t); 13 for(int k=1;k<=t;k++) 14 { 15 scanf("%d",&n); 16 for(int i=1;i<=n;i++) 17 { 18 scanf("%d",&num[i]); 19 a[i]=num[i]; 20 } 21 22 int ans=0,pos=0; 23 if(num[1]<num[2]) 24 { 25 int st=1,t=0; 26 while(num[st]<num[st+1]) 27 { 28 pos=st; 29 num[st]=t; 30 st++; t++; 31 } 32 pos++; 33 } 34 if(num[n]<num[n-1]) 35 { 36 int st=n,t=0; 37 while(num[st]<num[st-1]) 38 { 39 pos=st; 40 num[st]=t; 41 st--; t++; 42 } 43 pos--; 44 } 45 bool flag=true; 46 for(int i=2;i<n;i++) 47 { 48 flag=false; 49 if(num[i]<num[i-1]&&num[i]<num[i+1]) 50 { 51 int st=0,s=i; 52 while(num[s]<num[s-1]) 53 { 54 num[s]=st; 55 s--;st++; 56 } 57 num[s]=max(num[s-1],num[s+1])+1; 58 st=0;s=i; 59 while(num[s]<num[s+1]) 60 { 61 num[s]=st; 62 s++;st++; 63 } 64 num[s]=max(num[s-1],num[s+1])+1; 65 } 66 } 67 if(num[1]>num[2]+1) 68 num[1]=num[2]-1; 69 if(num[n]>num[n-1]+1) 70 num[n]=num[n-1]-1; 71 for(int i=1;i<=n;i++) 72 { 73 if(num[i]>num[i-1]&&num[i]>num[i+1]) 74 num[i]=max(num[i-1],num[i+1])+1; 75 ans+=a[i]-num[i]; 76 } 77 if(ans&1) 78 cout<<"Case "<<k<<": Alice"<<endl; 79 else 80 cout<<"Case "<<k<<": Bob"<<endl; 81 } 82 return 0; 83 }
H.汉明距离 (字符串贪心构造)
在信息理论中,两个相等长度的串之间的汉明距离是指相同位置字符不同的数量。换句话说,它计算将一个字符串更改为另一个字符串所需的最小替换次数,或者可能将一个字符串转换为另一个字符串的最小更改数。
假设有两个字符串s1,s2具有相同的长度,仅限于包含小写字符,找到一个相同长度的、字典序最小的字符串s,使得s1,s2与s的汉明距离相等。
一开始发现情况太多被劝退的,实际发现也没那么难以实现。emm...一言难尽。
1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<cstring> 5 #include<cmath> 6 using namespace std; 7 const int maxn=1e4+10; 8 char c1[maxn],c2[maxn],c3[maxn]; 9 int sum[maxn]; 10 char MIN(char a,char b) 11 { 12 for(char i='a'; i<='z'; i++) 13 { 14 if(i!=a&&i!=b) 15 return i; 16 } 17 } 18 int main() 19 { 20 int t; 21 while(~scanf("%d",&t)) 22 { 23 for(int i=1; i<=t; i++) 24 { 25 scanf("%s%s",c1,c2); 26 int len=strlen(c1); 27 sum[len]=0; 28 for(int j=len-1; j>=0; j--) 29 { 30 sum[j]=sum[j+1]; 31 if(c1[j]!=c2[j]) 32 sum[j]++; 33 } 34 int num=0; 35 for(int j=0; j<len; j++) 36 { 37 if(abs(num) < sum[j+1]||c1[j]==c2[j]) 38 { 39 c3[j]='a'; 40 if(c1[j]=='a'&&c2[j]!='a') 41 num++; 42 if(c1[j]!='a'&&c2[j]=='a') 43 num--; 44 continue; 45 } 46 char ch=MIN(c1[j],c2[j]); 47 if(ch=='a') 48 { 49 if(abs(num)<=sum[j+1]) 50 c3[j]=ch; 51 else if(num>0) 52 c3[j]=c2[j],num--; 53 else 54 c3[j]=c1[j],num++; 55 56 } 57 else if(ch=='b') 58 { 59 if((c1[j]=='a'&&num+1<=sum[j+1])||(c2[j]=='a'&&num-1>=-sum[j+1])) 60 { 61 c3[j]='a'; 62 if(c1[j]=='a') num++; 63 else num--; 64 continue; 65 } 66 if(abs(num)<=sum[j+1]) 67 c3[j]=ch; 68 else 69 { 70 c3[j]=max(c1[j],c2[j]); 71 if(c1[j]=='b') num++; 72 else num--; 73 } 74 } 75 else 76 { 77 if((c1[j]=='a'&&num+1<=sum[j+1])||(c2[j]=='a'&&num-1>=-sum[j+1])) 78 { 79 c3[j]='a'; 80 if(c1[j]=='a') num++; 81 else num--; 82 continue; 83 } 84 if((c1[j]=='b'&&num+1<=sum[j+1])||(c2[j]=='b'&&num-1>=-sum[j+1])) 85 86 { 87 c3[j]='b'; 88 if(c1[j]=='b') num++; 89 else num--; 90 continue; 91 } 92 else c3[j]=ch; 93 } 94 } 95 c3[len]='\0'; 96 printf("Case %d: %s\n",i,c3); 97 } 98 } 99 return 0; 100 }