• 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]='';
    74             printf("Case %d: %s
    ",i,c3);
    75         }
    76     }
    77     return 0;
    78 }
    View Code
  • 相关阅读:
    文件读写和进度条
    复选框选择变化(可以演化成简单的字符串拼接)
    读取文本方式的简单登录
    计算字符出现次数
    判断系统版本号
    DataTable合并
    获取单元格值的数据类型
    struts2 日期标签
    jsp获取枚举的值
    java web项目修改项目名称
  • 原文地址:https://www.cnblogs.com/Amaris-diana/p/10802973.html
Copyright © 2020-2023  润新知