给定一个数n,让你随便选用n个数构造一个序列a,满足以下条件:a1⊕a2⊕...⊕an=(a1+a2+...+an)/n ,输出序列a。

 题目思路:

该题要知道异或的性质:

        第一:只有二进制才能进行异或运行,所以等式左边需要转化成二进制进行运算。

        第二:a⊕a=0,a⊕0=a。也就是我们常在书上看到的1⊕1=0,1⊕0=1这样一个道理。

       然后根据第二条性质,我们知道,如果n为奇数个时候,且每个数字都相同,才会存在两边等式成立的情况。左边不管怎么进行异或,最后都会出现an⊕0=an的情况。反过来说,也只有a都相同时候且等于1时候,等式左右两边才会相同。

        如果n为偶数个时候,我们继续找特殊值能否成立。

        当n=2时候,发现只有a1=1,a2=3时候,a1⊕a2=2,才等于右边(1+3)/2=2。

        当n=4时候,a1=1,a2=3,a3=2,a4=2时候,a1⊕a2⊕a3⊕a4=2,右边(1+3+2+2)/4=2。

        当n=6时候,a1=1,a2=3,a3=2,a4=2,a5=2,a6=2时候,a1⊕a2⊕a3⊕a4⊕a5⊕a6=2,右边(1+3+2+2+2+2)/6=2。

        ...

        当n=n时候,a1=1,a2=3,a3=2 ....  an=2时候,a1⊕a2⊕a3⊕...⊕an=2,右边(1+3+2+...+2)/n=2。

        综上得出,n为奇数时候,a全为1;n为偶数时候,a为{1,3,2...2};

代码实现:

#include<stdio.h>

void f(){
	int n; 
	scanf("%d",&n);
	if(n%2==1){
		for(int i=0;i<n-1;i++){
			printf("1 ");
		}
		printf("1");
	}
	else{
		for(int i=0;i<n-2;i++)
			printf("2 ");
		printf("1 3");
	}
}

int main(){
	int a;
	scanf("%d",&a);
	while(a--){
		f();
	}
	return 0;
} 

总结:抓住序列编号的规律,才是解决问题的最好方法。

猜你喜欢

转载自blog.csdn.net/study_jiang_up/article/details/129268719