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

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

 G.Greatest Common Divisor(思维)

求相邻数的差值的gcd,对gcd分解素因子,对所有的素因子做一次遍历,找出最小答案。

几个样例: ans : 0 1 0 2

3
3 6 9
1
1
1
2
2
11 76

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<algorithm>
 5 #include<cmath>
 6 #define LL long long
 7 using namespace std;
 8 const int MAXN= 1e5+5;
 9 
10 LL t, n, a[MAXN], fac[100], cnt;
11 LL gcd(LL a, LL b){return b==0 ? a : gcd(b, a%b);}
12 void work(LL x){
13     LL temp = x;
14     for(LL i=2; i*i<=temp; i++)
15         if(x%i == 0) {
16             fac[++cnt] = i;
17             while(x%i == 0) x /= i;
18         }
19     if(x>1) fac[++cnt] = x;
20 }
21 int main()
22 {
23     LL Case = 0;
24     cin >> t;
25     while(t--){
26         cnt = 0;
27         bool flag1=true, flag2=true;
28         scanf("%lld", &n);
29         for(LL i=1; i<=n; i++) scanf("%lld", &a[i]);
30         sort(a+1, a+n+1);
31         n = unique(a+1, a+n+1) - a - 1 ;
32         printf("Case %lld: ", ++Case);
33 
34         if(n == 1){
35             if(a[1] == 1) cout << "1" << endl;
36             else cout << "0" << endl;
37             continue;
38         }
39 
40         LL temp = a[2]-a[1];
41         for(LL i=3; i<=n; i++)
42             temp = gcd(temp, a[i]-a[i-1]);
43 
44         if(temp == 1){
45             cout << "-1" << endl;
46             continue;
47         }
48         work(temp);
49         LL ans = 1e17;
50         for(LL i=1; i<=cnt; i++){
51             if(a[1] % fac[i] == 0) ans = 0;
52             ans = min(ans, fac[i]-(a[1]%fac[i]));
53         }
54         cout << ans << endl;
55     }
56 }
View Code

 

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                 else
47                 {
48                     char ch=MIN(c1[j],c2[j]);
49                     if(num>0)
50                     {
51                         if(ch<c2[j]&&num==sum[j+1])
52                             c3[j]=ch;
53                         else
54                         {
55                             c3[j]=c2[j];
56                             num--;
57                         }
58                     }
59                     else if(num<0)
60                     {
61                         if(ch<c1[j]&&-num==sum[j+1])
62                             c3[j]=ch;
63                         else
64                         {
65                             c3[j]=c1[j];
66                             num++;
67                         }
68                     }
69                     else
70                         c3[j]=ch;
71                 }
72             }
73             c3[len]='\0';
74             printf("Case %d: %s\n",i,c3);
75         }
76     }
77     return 0;
78 }
View Code

 

posted @ 2019-05-02 18:25  egoist的翻绳游戏  阅读(529)  评论(0编辑  收藏  举报