Codeforces Round #676 (Div. 2) XORwice、Putting Bricks in the Wall、Palindromifier
题目链接:XORwice
题意:给你两个数a、b。求一个数x,使得((a异或x)+(b异或x))这个值最小,输出最小那个x
题解:
输出(a|b)-(a&b)就行(猜了一手
代码:
#include<stdio.h> #include<string.h> #include<algorithm> #include<iostream> #include<queue> #include<vector> #define mem(x) memset(x,0,sizeof(x)) using namespace std; typedef long long ll; const int maxn=1e5+10; int main() { int t; scanf("%d",&t);; while(t--) { int a,b; scanf("%d%d",&a,&b); printf("%d\n",(a|b)-(a&b)); } return 0; }
题目链接:Putting Bricks in the Wall
题意:给你一个n*n的方形,每一个小格子有一个值(除了(1,1)和(n,n))。你从一个位置只能移动到与它相邻一条边的其他位置(也就是上下左右移动)
它需要从起点(1,1)移动到终点(n,n),你要保证这条路径上所经历过的所有格子的值都一样(除了(1,1)和(n,n))
现在你可以反转最多两个格子的值(也就是把一个格子的值从0变1,或从1变0),使得找不到一条满足条件从起点(1,1)到终点(n,n)的路径
然后输出你需要反转的格子的坐标
题解:
只需要让(1,1)位置周围两个点 和(n,n)周围两个点的值变成相反的就可以了
就比如让(1,2)和(2,1)位置的值变成1,让 (n-1,n)和(n,n-1)位置的点变成0
代码:
#include<stdio.h> #include<string.h> #include<algorithm> #include<iostream> #include<queue> #include<vector> #define mem(x) memset(x,0,sizeof(x)) using namespace std; typedef long long ll; const int maxn=1e3+10; const int INF=0x3f3f3f3f; char s[maxn][maxn]; int main() { int t; scanf("%d",&t);; while(t--) { int n; scanf("%d",&n); for(int i=1;i<=n;++i) { scanf("%s",s[i]+1); } int one_st=0,zero_st=0,one_la=0,zero_la=0,one_st2=0,zero_st2=0,one_la2=0,zero_la2=0; if(s[1][2]=='1') one_st++; else zero_st++; if(s[2][1]=='1') one_st2++; else zero_st2++; if(s[n][n-1]=='1') one_la++; else zero_la++; if(s[n-1][n]=='1') one_la2++; else zero_la2++; int res=INF; res=min(res,one_st2+one_st+zero_la+zero_la2); int temp=res,flag=0; res=min(res,zero_st2+zero_st+one_la2+one_la); if(temp==res) flag=1; printf("%d\n",res); if(flag) { if(s[2][1]=='1') printf("2 1\n"); if(s[1][2]=='1') printf("1 2\n"); if(s[n][n-1]=='0') printf("%d %d\n",n,n-1); if(s[n-1][n]=='0') printf("%d %d\n",n-1,n); } else { if(s[2][1]=='0') printf("2 1\n"); if(s[1][2]=='0') printf("1 2\n"); if(s[n][n-1]=='1') printf("%d %d\n",n,n-1); if(s[n-1][n]=='1') printf("%d %d\n",n-1,n); } } return 0; }
题目链接:Palindromifier
题意:
给你一个字符串s(下标从1开始,长度为n),你有两种操作,你最多使用30次操作,你要保证经过操作之后的字符串是一个回文字符串,且这个回文字符串的长度不超过1e6
操作一、从区间[2,n-1]这个区间内挑一个x,然后把下标区间为[2,x]这一个子串倒过来(也就是abc变成cba)之后追加到原串的头部
操作二、从区间[2,n-1]这个区间内挑一个x,然后把下标区间为[x,n-1]这一个子串倒过来(也就是abc变成cba)之后追加到原串的尾部
题解:
#include<stdio.h> #include<string.h> #include<algorithm> #include<iostream> #include<queue> #include<vector> #define mem(x) memset(x,0,sizeof(x)) using namespace std; typedef long long ll; const int maxn=1e5+10; const int INF=0x3f3f3f3f; char s[maxn]; int main() { scanf("%s", s); int l = strlen(s); printf("3\n"); printf("R %d\n", l - 1); printf("L %d\n", l); printf("L 2\n"); return 0; }