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
*/

 

posted @ 2020-11-16 00:02  hachuochuo  阅读(108)  评论(0编辑  收藏  举报