A.
按二进制位从高到低贪心
1 #include<bits/stdc++.h> 2 using namespace std; 3 int T,a,b; 4 int main() 5 { 6 scanf("%d",&T); 7 while(T--) 8 { 9 scanf("%d%d",&a,&b); 10 int x=0; 11 for(int i=30;i>=0;--i)if((a&(1<<i))&&(b&(1<<i)))x|=(1<<i); 12 printf("%d ",(a^x)+(b^x)); 13 } 14 }
B.
左上角周围两个和右下角周围两个中翻转最多两个就行了
1 #include<bits/stdc++.h> 2 #define maxn 205 3 using namespace std; 4 int T,n; 5 char s[maxn][maxn]; 6 int main() 7 { 8 scanf("%d",&T); 9 while(T--) 10 { 11 scanf("%d",&n); 12 for(int i=1;i<=n;++i)scanf("%s",s[i]+1); 13 if(s[1][2]=='0'&&s[2][1]=='0') 14 { 15 if(s[n][n-1]=='1'&&s[n-1][n]=='1') 16 { 17 printf("0 "); 18 } 19 else if(s[n][n-1]=='0'&&s[n-1][n]=='1') 20 { 21 printf("1 "); 22 printf("%d %d ",n,n-1); 23 } 24 else if(s[n][n-1]=='1'&&s[n-1][n]=='0') 25 { 26 printf("1 "); 27 printf("%d %d ",n-1,n); 28 } 29 else 30 { 31 printf("2 "); 32 printf("%d %d ",n,n-1); 33 printf("%d %d ",n-1,n); 34 } 35 } 36 else if(s[1][2]=='1'&&s[2][1]=='0') 37 { 38 if(s[n][n-1]=='1'&&s[n-1][n]=='1') 39 { 40 printf("1 "); 41 printf("1 2 "); 42 } 43 else if(s[n][n-1]=='0'&&s[n-1][n]=='1') 44 { 45 printf("2 "); 46 printf("%d %d ",2,1); 47 printf("%d %d ",n-1,n); 48 } 49 else if(s[n][n-1]=='1'&&s[n-1][n]=='0') 50 { 51 printf("2 "); 52 printf("%d %d ",2,1); 53 printf("%d %d ",n,n-1); 54 } 55 else 56 { 57 printf("1 "); 58 printf("%d %d ",2,1); 59 } 60 } 61 else if(s[1][2]=='0'&&s[2][1]=='1') 62 { 63 if(s[n][n-1]=='1'&&s[n-1][n]=='1') 64 { 65 printf("1 "); 66 printf("2 1 "); 67 } 68 else if(s[n][n-1]=='0'&&s[n-1][n]=='1') 69 { 70 printf("2 "); 71 printf("1 2 "); 72 printf("%d %d ",n-1,n); 73 } 74 else if(s[n][n-1]=='1'&&s[n-1][n]=='0') 75 { 76 printf("2 "); 77 printf("1 2 "); 78 printf("%d %d ",n,n-1); 79 } 80 else 81 { 82 printf("1 "); 83 printf("1 2 "); 84 } 85 } 86 else 87 { 88 if(s[n][n-1]=='1'&&s[n-1][n]=='1') 89 { 90 printf("2 "); 91 printf("%d %d ",n,n-1); 92 printf("%d %d ",n-1,n); 93 } 94 else if(s[n][n-1]=='0'&&s[n-1][n]=='1') 95 { 96 printf("1 "); 97 printf("%d %d ",n-1,n); 98 } 99 else if(s[n][n-1]=='1'&&s[n-1][n]=='0') 100 { 101 printf("1 "); 102 printf("%d %d ",n,n-1); 103 } 104 else 105 { 106 printf("0 "); 107 } 108 } 109 } 110 }
C.
考虑把第二个字符翻到前面形成回文串(s_2 s_1 s_2),然后整个复制翻到后面,那么就只差最后一个字符了,由前面的小回文串把倒数第二个翻过去就行了
1 #include<bits/stdc++.h> 2 #define maxn 100005 3 using namespace std; 4 char s[maxn]; 5 int n; 6 int main() 7 { 8 scanf("%s",s+1); 9 n=strlen(s+1); 10 puts("3"); 11 printf("L %d ",2); 12 printf("R %d ",2); 13 printf("R %d ",2*n-1); 14 }
D.
考虑做类似最短路的松弛操作,把每种向量的代价弄成最优的
然后就一定是两种走法拼到一起
1 #include<bits/stdc++.h> 2 #define ll long long 3 using namespace std; 4 int T; 5 ll x,y; 6 ll c1,c2,c3,c4,c5,c6; 7 ll a[8][8]; 8 int main() 9 { 10 scanf("%d",&T); 11 while(T--) 12 { 13 scanf("%lld%lld",&x,&y); 14 scanf("%lld%lld%lld%lld%lld%lld",&c1,&c2,&c3,&c4,&c5,&c6); 15 while(1) 16 { 17 ll p2,p3,p5,p6; 18 p2=min(c2,c1+c3); 19 p3=min(c3,c2+c4); 20 p5=min(c5,c4+c6); 21 p6=min(c6,c1+c5); 22 if(c2==p2&&c3==p3&&c5==p5&&c6==p6)break; 23 c2=p2;c3=p3;c5=p5;c6=p6; 24 } 25 ll ans=0; 26 if(x>0)ans+=x*c6;else ans+=(-x)*c3; 27 if(y>0)ans+=y*c2;else ans+=(-y)*c5; 28 if(x>0) 29 { 30 ll res=0; 31 res+=x*c1; 32 if(y<x)res+=c5*(x-y); 33 else res+=c2*(y-x); 34 ans=min(ans,res); 35 } 36 else 37 { 38 ll res=0; 39 res+=(-x)*c4; 40 if(y<x)res+=c5*(x-y); 41 else res+=c2*(y-x); 42 ans=min(ans,res); 43 } 44 if(y>0) 45 { 46 ll res=0; 47 res+=y*c1; 48 if(x<y)res+=c3*(y-x); 49 else res+=c6*(x-y); 50 ans=min(ans,res); 51 } 52 else 53 { 54 ll res=0; 55 res+=(-y)*c4; 56 if(x<y)res+=c3*(y-x); 57 else res+=c6*(x-y); 58 ans=min(ans,res); 59 } 60 printf("%lld ",ans); 61 } 62 }
E.
考虑最后的合并是一个二叉树结构,在二叉树的奇数层(根深度为1)的叶子贡献为-1,偶数层贡献为+1
那么我们假设第(k)层叶子的权值为(frac{1}{2^k}),那么总权值是(1)
在mod 3意义下,奇数层权值是(2),偶数层权值是(1)
这等价于前面的贡献
我们将叶子从左到右的权值做前缀和,在mod 3意义下一定是从(0)开始到(1)结束
只要这棵二叉树能构造出来,这种方案就一定合法
二叉树能构造出来等价于一定有一个位置为(2),这个可以用归纳证明
然后(dp[i][0/1/2][0/1])表示dp到第(i)位,前缀和mod 3为多少,然后有没有经过(2)的最大值
1 #include<bits/stdc++.h> 2 #define maxn 200005 3 #define ll long long 4 using namespace std; 5 int n; 6 ll a[maxn]; 7 ll dp[maxn][3][2]; 8 const ll inf = (ll)1e18; 9 int main() 10 { 11 scanf("%d",&n); 12 for(int i=1;i<=n;++i)scanf("%lld",&a[i]); 13 if(n==1) 14 { 15 printf("%lld ",a[1]); 16 return 0; 17 } 18 for(int i=0;i<=n;++i) 19 for(int j=0;j<3;++j) 20 for(int k=0;k<2;++k)dp[i][j][k]=-inf; 21 dp[0][0][0]=0; 22 for(int i=0;i<n;++i) 23 for(int j=0;j<3;++j) 24 for(int k=0;k<2;++k) 25 { 26 int p; 27 p=k; 28 if((j+1)%3==2)p=1; 29 dp[i+1][(j+1)%3][p]=max(dp[i+1][(j+1)%3][p],dp[i][j][k]+a[i+1]); 30 p=k; 31 if((j+2)%3==2)p=1; 32 dp[i+1][(j+2)%3][p]=max(dp[i+1][(j+2)%3][p],dp[i][j][k]-a[i+1]); 33 } 34 cout<<dp[n][1][1]<<endl; 35 }