Powerful Ksenia ----- CodeForces - 1438D(构造)
题意:
一个长度为n的数组a,每一步操作,选择三个下标 i、j、k,使 a[ i ]=a[ j ]=a[ k ]=a[ i ]^a[ j ]^a[ k ] ,问:能否在n步呢使这个数组所有的数都相同,输出步数和每步的操作。
思路:
首先:我们可以发现 形如 x x y 三个异或结果一定为y 。
n为奇数:如a b c d e -> x x x d e(1 2 3) -> x x y y y(3 4 5) -> y y y y y(1 2 3)
n为偶数:对前n-1个实行和奇数次一样的操作后,最终一定会剩下一个,那么要让剩下一个也和前面的一样,就需要判断最后一个与前面n-1个数的异或结果是否相同,即n个数的异或值是否为0。
代码:
int a[100005]; int main() { int n,sum=0; scanf("%d",&n); for(int i=1;i<=n;i++){ scanf("%d",&a[i]); sum=sum^a[i]; } if(n%2==0){ if(sum==0){ int num=1; printf("YES\n%d\n",n-3); while(num+2<=n-1){ printf("%d %d %d\n",num,num+1,num+2); a[num]=a[num+1]=a[num+2]=a[num]^a[num+1]^a[num+2]; num+=2; } num-=4; while(num>=1){ printf("%d %d %d\n",num,num+1,num+2); a[num]=a[num+1]=a[num+2]=a[num]^a[num+1]^a[num+2]; num-=2; } }else{ printf("NO\n"); } }else{ int num=1; printf("YES\n%d\n",n-2); while(num+2<=n){ printf("%d %d %d\n",num,num+1,num+2); a[num]=a[num+1]=a[num+2]=a[num]^a[num+1]^a[num+2]; num+=2; } num-=4; while(num>=1){ printf("%d %d %d\n",num,num+1,num+2); a[num]=a[num+1]=a[num+2]=a[num]^a[num+1]^a[num+2]; num-=2; } } return 0; } /* x^x^y==y //奇数 a b c d e f g h i x x x d e f g h i ->1 2 3 x x y y y f g h i ->3 4 5 x x y y z z z h i ->5 6 7 x x y y z z k k k ->7 8 9 x x y y k k k k k ->5 6 7 x x k k k k k k k ->3 4 5 k k k k k k k k k ->1 2 3 //偶数 a b c d e f x x x d e f ->1 2 3 x x y y y f ->3 4 5 y y y y y f ->1 2 3 因为 y^f==0 -> y==f */
越自律,越自由