要使值最小,我们要尽可能将1变成0,如果一个位上ai与bi不同,那么无论x这位取什么都没有影响,如果同为0,那么取0,如果同为1,取1。
#include <iostream> #include <stdio.h> #include <cstring> #include <algorithm> using namespace std; int T,a,b; int main() { scanf("%d",&T); while(T--) { scanf("%d%d",&a,&b); int ans=0; for(int i=31;i>=0;i--) { if(((1<<i)&a)==((1<<i)&b)) { if((1<<i)&a) ans|=(1<<i); } } printf("%d\n",(ans^a)+(ans^b)); } return 0; }我们发现最多需要两次操作去修改起点附近的五个格(1,2)、(1,3)、(2,1)、(2,2)、(3,1),就一定能让起点出不去,不会的可以自己尝试下。
#include <iostream> #include <stdio.h> #include <cstring> #include <algorithm> using namespace std; const int N=210; int T,n; char mp[N][N]; int c; int x[5]; void out1() { puts("2"); puts("1 2"); puts("2 1"); } void out2() { int cnt=0; int ans[2]; for(int i=2;i<=4;++i) { if(x[i]==x[1]) { ans[c++]=i; } } printf("%d\n",c); for(int i=0;i<c;++i) { if(ans[i]==2) puts("2 2"); if(ans[i]==3) puts("1 3"); if(ans[i]==4) puts("3 1"); } } void out4(int i) { if(i==2) puts("2 2"); if(i==3) puts("1 3"); if(i==4) puts("3 1"); } void out3() { for(int i=2;i<=4;++i) { if(x[i]==x[0]) c++; } if(c==2) { puts("2"); puts("1 2"); for(int i=2;i<=4;++i) { if(x[i]!=x[0]) out4(i); } } else { puts("2"); puts("2 1"); for(int i=2;i<=4;++i) { if(x[i]==x[0]) out4(i); } } } int main() { scanf("%d",&T); while(T--) { c=0; scanf("%d",&n); for(int i=0;i<n;++i) scanf("%s",mp[i]); x[0]=mp[0][1]-'0'; x[1]=mp[1][0]-'0'; x[2]=mp[1][1]-'0'; x[3]=mp[0][2]-'0'; x[4]=mp[2][0]-'0'; if(x[0]==x[1]) { if(x[1]==x[2]&&x[2]==x[3]&&x[3]==x[4]) { if(x[1]==x[2]) { out1(); continue; } } else { out2(); continue; } } else { if(x[2]==x[3]&&x[3]==x[4]) { if(x[0]==x[2]) { puts("1"); puts("1 2"); continue; } else { puts("1"); puts("2 1"); continue; } } else { out3(); continue; } } } return 0; }构造题,我们可以找到一种通解,L 2,L 2,R 2,R 2*len+1。
#include <iostream> #include <stdio.h> #include <cstring> #include <algorithm> using namespace std; const int N=1e5+5; char s[N]; int len; int main() { scanf("%s",s); len=strlen(s); puts("4"); puts("L 2"); puts("L 2"); puts("R 2"); printf("R %d\n",2*len+1); return 0; }对于终点(x,y),我们一共有三种方式,直接通过单操作x再单操作y到达,或通过同时操作到(x,x)再通过单次操作到(x,y),或者通过同时操作到(y,y)再通过单次操作到(x,y)。讨论一下即可。
#include <iostream> #include <stdio.h> #include <cstring> #include <algorithm> using namespace std; typedef long long ll; struct node { int x,y; }p; int T; int c[7]; ll get_ans() { ll t1,t2,t3; t1=t2=t3=0; if(p.x>=0) { t1+=1ll*p.x*c[6]; t2+=1ll*p.x*c[1]; } else { t1+=1ll*-p.x*c[3]; t2+=1ll*-p.x*c[4]; } if(p.y>=0) { t1+=1ll*p.y*c[2]; t3+=1ll*p.y*c[1]; } else { t1+=1ll*-p.y*c[5]; t3+=1ll*-p.y*c[4]; } if(p.x>=p.y) { t2+=1ll*abs(p.x-p.y)*c[5]; t3+=1ll*abs(p.x-p.y)*c[6]; } else { t2+=1ll*abs(p.x-p.y)*c[2]; t3+=1ll*abs(p.x-p.y)*c[3]; } return min(t1,min(t2,t3)); } int main() { scanf("%d",&T); while(T--) { scanf("%d%d",&p.x,&p.y); for(int i=1;i<=6;++i) scanf("%d",&c[i]); printf("%lld\n",get_ans()); } return 0; }