Codeforces Global Round 1 做题记录
Posted uuzlove
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces Global Round 1 做题记录相关的知识,希望对你有一定的参考价值。
A.
题解:快速幂
代码:
1 #include<bits/stdc++.h> 2 #define ll long long 3 #define maxn 100005 4 using namespace std; 5 const ll mod=2; 6 ll b,k; 7 ll a[maxn]; 8 ll fastpow(ll a,ll p) 9 { 10 ll ans=1; 11 while(p) 12 { 13 if(p&1)ans=ans*a%mod; 14 a=a*a%mod;p>>=1; 15 } 16 return ans; 17 } 18 int main() 19 { 20 scanf("%I64d%I64d",&b,&k); 21 for(int i=1;i<=k;++i)scanf("%I64d",&a[i]); 22 ll n=0; 23 for(int i=1;i<=k;++i)n=(n+a[i]*fastpow(b,k-i)%mod)%mod; 24 if(n)puts("odd"); 25 else puts("even"); 26 }
B.
题解:考虑两两相邻点之间的距离,贪心取最小的k-1个
1 #include<bits/stdc++.h> 2 #define maxn 100005 3 using namespace std; 4 int n,m,k; 5 int a[maxn]; 6 priority_queue<int,vector<int>,greater<int> >q; 7 int main() 8 { 9 scanf("%d%d%d",&n,&m,&k); 10 int ans=n; 11 for(int i=1;i<=n;++i)scanf("%d",&a[i]); 12 k=n-k; 13 for(int i=1;i<n;++i)q.push(a[i+1]-a[i]-1); 14 while(k--) 15 { 16 int t=q.top(); 17 q.pop(); 18 ans+=t; 19 } 20 printf("%d ",ans); 21 return 0; 22 }
C.
题解:找规律,除了2^k-1以外其他情况ans=2^p-1(其中p为满足ans>a的最小的数),2^k-1的情况打表就行
1 #include<bits/stdc++.h> 2 using namespace std; 3 int q; 4 int vis[]={0,0,1,1,5,1,21,1,85,73,341,89,1365,1,5461,4681,21845,1,87381,1,349525,299593,1398101,178481,5592405,1082401}; 5 int main() 6 { 7 scanf("%d",&q); 8 while(q--) 9 { 10 int a; 11 scanf("%d",&a); 12 int p=1; 13 while(((1<<p)-1)<a)p++; 14 if(a==((1<<p)-1)) 15 { 16 if(!vis[p]) 17 { 18 int ans=0; 19 for(int b=1;b<a;++b)ans=max(ans,__gcd(a^b,a&b)); 20 vis[p]=ans; 21 printf("%d ",ans); 22 } 23 else printf("%d ",vis[p]); 24 } 25 else printf("%d ",(1<<p)-1); 26 } 27 return 0; 28 }
D.
题解:考虑3个三元组[ i-1 ,i ,i+1 ]可以被拆成[ i-1, i-1, i-1 ] , [ i , i , i ] , [ i+1, i+1, i+1 ],所以每个状态中这样的三元组不会超过2个
然后dp(i,j,k)表示有j个[ i-1 ,i ,i+1 ] , k个[ i , i+1 , i+2 ],转移每次枚举一个 l ,表示dp(i+1,k,l),其中多l个[ i+1 , i+2, i+3 ]
那相同的三元组怎么处理?( num(i) - j -k -l )/3 个,直接加上就好了
1 #include<bits/stdc++.h> 2 #define inf 1000000000 3 #define maxn 1000005 4 using namespace std; 5 int n,m; 6 int has[maxn]; 7 int dp[maxn][3][3]; 8 int main() 9 { 10 scanf("%d%d",&n,&m); 11 for(int x,i=1;i<=n;++i) 12 { 13 scanf("%d",&x); 14 has[x]++; 15 } 16 for(int i=0;i<=m;++i) 17 { 18 for(int j=0;j<=2;++j) 19 { 20 for(int k=0;k<=2;++k)dp[i][j][k]=-inf; 21 } 22 } 23 dp[0][0][0]=0; 24 for(int i=0;i<m;++i) 25 { 26 for(int j=0;j<=min(has[i],2);++j) 27 { 28 for(int k=0;k<=min(has[i+1],2);++k) 29 { 30 for(int l=0;l<=min(has[i+2],2);++l)if(has[i+1]>=j+k+l) 31 { 32 dp[i+1][k][l]=max(dp[i+1][k][l],dp[i][j][k]+l+(has[i+1]-j-k-l)/3); 33 } 34 } 35 } 36 } 37 printf("%d ",dp[m][0][0]); 38 return 0; 39 }
E.
题解:原题,以前有一道前缀和类似的结论
考虑每次操作,本质上是在差分数组中交换两个数的位置
我们只需要判断差分数组是否同构以及原数组首尾是否相同就行了
1 #include<bits/stdc++.h> 2 #define ll long long 3 #define maxn 100005 4 using namespace std; 5 int n; 6 ll c[maxn],t[maxn],x[maxn],y[maxn]; 7 int main() 8 { 9 scanf("%d",&n); 10 for(int i=1;i<=n;++i)scanf("%I64d",&c[i]); 11 for(int i=1;i<=n;++i)scanf("%I64d",&t[i]); 12 if(c[1]!=t[1]||c[n]!=t[n]) 13 { 14 puts("No"); 15 return 0; 16 } 17 else 18 { 19 for(int i=2;i<=n;++i)x[i]=c[i]-c[i-1]; 20 for(int i=2;i<=n;++i)y[i]=t[i]-t[i-1]; 21 sort(x+1,x+n+1); 22 sort(y+1,y+n+1); 23 bool yes=1; 24 for(int i=1;i<=n;++i)if(x[i]!=y[i])yes=0; 25 if(yes)puts("Yes"); 26 else puts("No"); 27 } 28 return 0; 29 }
F,G,H留坑
以上是关于Codeforces Global Round 1 做题记录的主要内容,如果未能解决你的问题,请参考以下文章