2018 CCPC 桂林站(upc复现赛)补题

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 }
View Code

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 }
View Code

猜你喜欢

转载自www.cnblogs.com/Amaris-diana/p/10802973.html