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
*/
越自律,越自由

浙公网安备 33010602011771号