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 }
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 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]='