一本通1667巧克力棒
1667:巧克力棒
时间限制: 1000 ms 内存限制: 524288 KB【题目描述】
原题来自:BZOJ 1299
TBL 和 X 用巧克力棒玩游戏。每次一人可以从盒子里取出若干条巧克力棒,或是将一根取出的巧克力棒吃掉正整数长度。TBL 先手两人轮流,无法操作的人输。他们以最佳策略一共进行了 10 轮(每次一盒)。你能预测胜负吗?
【输入】
输入数据共 20 行。第 2i−1 行一个正整数 Ni ,表示第 i 轮巧克力棒的数目。第 2i 行 Ni 个正整数 Li,j,表示第 i 轮巧克力棒的长度。
【输出】
输出数据共 10 行。每行输出 YES 或 NO,表示 TBL 是否会赢。如果胜则输出 NO,否则输出 YES。
【输入样例】
3
11 10 15
5
13 6 7 15 3
2
15 12
3
9 7 4
2
15 12
4
15 12 11 15
3
2 14 15
3
3 16 6
4
1 4 10 3
5
8 7 7 5 12
【输出样例】
NO
YES
YES
YES
NO
YES
YES
YES
NO
【提示】
数据范围与提示:
对于 20% 的数据,N≤5,L≤100;
对于 40% 的数据,N≤7;
对于 50% 的数据,L≤5000;
对于全部数据,N≤14,L≤109 。
sol:先手要胜的话,取m根棒,使得这些棒异或和为0,且剩余的不可能取出异或和为0的情况,(实际上m就是巧克力棒的xor和为0的最长子序列)。
%%%hzwer的题解
题解
先从n根巧克力棒中取出m(m>0)根,使得这m根巧克力棒的xor和为0(也就是把nim游戏的必败状态留给对方),同时使得剩下的n-m根巧克力棒无论怎么取,xor和都不为0。(实际上m就是巧克力棒的xor和为0的最长子序列)。
这么一来,对手就面临一个必败状态的nim游戏。如果他从n-m根中取新的巧克力棒,实际上就是新建一个xor和不为0的nim游戏,这时轮到己方操作只要将这个新的nim游戏取到xor和为0即可。(也就是让对方再次面临所有nim游戏均为必败状态的局面)。
寻找是否有Xor和=0的巧克力棒子序列,直接DFS无压力。
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
以上是对大佬的膜拜
#include <bits/stdc++.h> using namespace std; typedef int ll; inline ll read() { ll s=0; bool f=0; char ch=' '; while(!isdigit(ch)) { f|=(ch=='-'); ch=getchar(); } while(isdigit(ch)) { s=(s<<3)+(s<<1)+(ch^48); ch=getchar(); } return (f)?(-s):(s); } #define R(x) x=read() inline void write(ll x) { if(x<0) { putchar('-'); x=-x; } if(x<10) { putchar(x+'0'); return; } write(x/10); putchar((x%10)+'0'); return; } #define W(x) write(x),putchar(' ') #define Wl(x) write(x),putchar('\n') const int N=20; int n,L[N]; bool ans; inline void dfs(int Pos,int Xor,bool Flag) { if(Pos==n+1) { if((Xor==0)&&Flag) ans=1; return; } dfs(Pos+1,Xor,Flag); dfs(Pos+1,(Xor^L[Pos]),(Flag|1)); } int main() { int i,T=10; while(T--) { ans=0; R(n); for(i=1;i<=n;i++) R(L[i]); dfs(1,0,0); if(ans) puts("NO"); else puts("YES"); } return 0; }