[CSP-S模拟测试]:最大异或和(数学)
题目传送门(内部题81)
输入格式
第一行一个整数$T(T\leqslant 20)$,表示测试数据组数
接下来$T$组,对于每一组,第一行一个整数$n$
第二行有$n$个整数,为$w_1,w_2...w_n$
接下来$n-1$行,每行两个整数$x,y$,表示$x$和$y$之间有一条边连接
输出格式
对于每一组,答案只有一行,如果小$Q$获胜输出$Q$,小$T$获胜输出$T$,如果平局输出$D$。
样例
样例输入:
2
3
2 2 2
1 2
1 3
4
7 1 4 2
1 2
1 3
2 4
样例输出:
Q
D
数据范围与提示
样例解释:
在第一组中,小$Q$选择任意一个节点,分数为$2$,小$T$选择剩下两个节点,分数为$0$,小$Q$获胜
在第二组中,小$Q$最好只能和小$T$平局,所以输出$D$
数据范围:
对于$30\%$的数据,$n\leqslant 20$
对于$100\%$的数据,$n\leqslant 100,000,w_i\leqslant 10^9$。
题解
小$Q$肯定不可能输,平局的情况当且仅当所有的$w_i$异或和为$0$时才能发生,否则小$Q$一定不能获胜。
因为出题人出此题意在送分,于是可能有各种不同的错解可以通过此题(听说对拍只能抗住$6,7$个点的假$DP$还能拿到$90$分)……
时间复杂度:$\Theta(T\times n)$。
期望得分:$100$分。
实际得分:$100$分。
代码时刻
#include<bits/stdc++.h>
using namespace std;
int n;
int w;
int XOR;
int main()
{
int T;scanf("%d",&T);
while(T--)
{
scanf("%d",&n);XOR=0;
for(int i=1;i<=n;i++)
{
scanf("%d",&w);
XOR^=w;
}
for(int i=1;i<n;i++)
scanf("%d%d",&w,&w);
if(XOR)puts("Q");
else puts("D");
}
return 0;
}
rp++