本文已参与「新人创作礼」活动,一起开启掘金创作之路。
@TOC
Codeforces Round #717 (Div. 2)-B. AGAGA XOOORRR
传送门 Time Limit: 1 second Memory Limit: 256 megabytes
Problem Description
Baby Ehab is known for his love for a certain operation. He has an array of length , and he decided to keep doing the following operation on it:
Now he asks you if he can make all elements of the array equal. Since babies like to make your life harder, he requires that you leave at least elements remaining.
Input
The first line contains an integer () — the number of test cases you need to solve.
The first line of each test case contains an integers () — the number of elements in the array .
The second line contains space-separated integers , , , () — the elements of the array .
Output
If Baby Ehab can make all elements equal while leaving at least elements standing, print "YES". Otherwise, print "NO".
Sample Input
2
3
0 2 2
4
2 3 1 10
Sample Onput
YES
NO
Note
In the first sample, he can remove the first elements, and , and replace them by . The array will be , so all the elements are equal.
In the second sample, there's no way to make all the elements equal.
题目大意
给你个数,你可以选择其中的任意两个进行异或操作,这样两个数就变成了一个数。 问你能不能使这个数最终的异或结果为不少于个的相同的数。
解题思路
首先要明白几个数相互异或,不论顺序如何,最终结果是不受影响的。 同时,两个相同的数异或结果是。 我们可以先让所有的这个数全部异或,得到一个结果。
如果这个结果是,就说明得到这个结果的上一步是两个相同的数,即,只有两个相同的数异或才能得到。这样就说明可以找到一种异或顺序,使得最终异或结果是两个相等的数。就直接输出YES
即可。
否则,如果结果想要是YES
,就必须至少能异或成个相同的数(题目说了不能是个相同的数)。 这个相同的数异或得到的结果就是所有数异或得到的结果。 于是我们就从头开始异或,直到得到这个最终的异或结果,这就得到了三个数中的一个数。从下一个数开始逐个异或,知道可以再得到一个与最终结果相同的数为止,我们就得到了三个数中的第二个。剩下的数全部异或起来一定是结果这个数。这样的话就输出YES
。
如果有同学想问为什么输出YES
的话,最终结果一定可以是个或个相同的数,而不是个或个呢?那么请看下面:
假设最终我们能够得到个相同的数,那么我们把这个相同的数分成两组,一组有两个数。则每组的两个数异或,原本的个数就变成了异或后的组。所以如果能最终能得到个相同的数,就一定能得到个相同的数。
同理,如果能分成组,就选其中的个数相异或变成一个数,就得到了相同的个数。所以如果最终能得到个相同的数,就一定能得到个相同的数。
如果还不太懂可以看看代码:
AC代码
#include <bits/stdc++.h>
using namespace std;
#define mem(a) memset(a, 0, sizeof(a))
#define dbg(x) cout << #x << " = " << x << endl
#define fi(i, l, r) for (int i = l; i < r; i++)
#define cd(a) scanf("%d", &a)
typedef long long ll;
int a[2020];
void solve()
{
int n;
cin>>n;
int res=0;//所有的数全部异或起来,最终结果是res
fi(i,0,n)//for(int i=0;i<n;i++)
{
cd(a[i]);//scanf("%d", &a[i]);
res^=a[i];//res异或上a[i]
}
if(res==0)//如果最终结果是0,那么得到0的上一步一定是两个相同的数
{
puts("YES");//所以我们可以直接输出YES并退出
return;
}
int s=0;//一些数异或起来得到的结果
int loc=0;//下标从第一个数开始
for(loc=0;loc<n;loc++)
{
s^=a[loc];//异或上a[i]
if(s==res)break;//如果前面一些数异或得到的结果已经是最终答案了,就找到了这3个数中的一个,就退出。
}
if(loc>=n-2)//如果不能再找到两个相同的数
{
puts("NO");//输出NO
return;
}
loc++;//下标从下一个未异或过的数开始
s=0;//一串异或起来的结果
for(;loc<n-1;loc++)
{
s^=a[loc];//异或上a[loc]
if(s==res)break;//如果结果是最终结果,就找到了第二个数
}
if(s!=res)//如果这一串异或起来不是最终结果
{
puts("NO");//就不行
return;
}
loc++;//从下一个数开始异或
s=0;//第三串异或的结果
for(;loc<n;loc++)//这次要异或到最后
{
s^=a[loc];//异或上a[loc]
}
if(s==res)//如果第3串异或的结果也是最终结果
puts("YES");//可以
else//否则
puts("NO");//不行
return;
}
int main()
{
int N;
cin>>N;//N组测试样例
while(N--)
{
solve();
}
return 0;
}
如果哪里看不懂可以在下面评论留言
同步发文于我的CSDN,原创不易,转载请附上原文链接哦~
Tisfy:letmefly.blog.csdn.net/article/det…