1. 程式人生 > >【bzoj1299】[LLH邀請賽]巧克力棒 博弈+模擬

【bzoj1299】[LLH邀請賽]巧克力棒 博弈+模擬

etc pre 所有 def 數據 out 長子 題解 output

Description

TBL和X用巧克力棒玩遊戲。每次一人可以從盒子裏取出若幹條巧克力棒,或是將一根取出的巧克力棒吃掉正整數長度。TBL先手兩人輪流,無法操作的人輸。 他們以最佳策略一共進行了10輪(每次一盒)。你能預測勝負嗎?

Input

輸入數據共20行。 第2i-1行一個正整數Ni,表示第i輪巧克力棒的數目。 第2i行Ni個正整數Li,j,表示第i輪巧克力棒的長度。

Output

輸出數據共10行。 每行輸出“YES”或“NO”,表示TBL是否會贏。如果勝則輸出”NO”,否則輸出”YES”

Sample Input

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

Sample Output

YES
NO
YES
YES
YES
NO
YES
YES
YES
NO

HINT

20%的分數,N<=5,L<=100。

40%的分數,N<=7。 50%的分數,L<=5,000。

100%的分數,N<=14,L<=1,000,000,000。

題解

先從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無壓力。

 1 #include<cstring>
 2 #include<cmath>
 3 #include<algorithm>
 4 #include<iostream>
 5 #include<cstdio>
 6
7 #define ll long long 8 using namespace std; 9 inline int read() 10 { 11 int x=0,f=1;char ch=getchar(); 12 while(ch>9||ch<0){if (ch==-) f=-1;ch=getchar();} 13 while(ch<=9&&ch>=0){x=(x<<3)+(x<<1)+ch-0;ch=getchar();} 14 return x*f; 15 } 16 17 int n; 18 int a[20]; 19 bool flag; 20 21 void dfs(int deep,int num) 22 { 23 if (flag) return; 24 if (deep==n) return; 25 deep++; 26 if ((num^a[deep])==0) flag=1; 27 else 28 { 29 dfs(deep,num); 30 dfs(deep,num^a[deep]); 31 } 32 } 33 int main() 34 { 35 while(~scanf("%d",&n)) 36 { 37 for (int i=1;i<=n;i++)a[i]=read(); 38 flag=0,dfs(0,0); 39 if (flag) printf("NO\n"); 40 else printf("YES\n"); 41 } 42 }

【bzoj1299】[LLH邀請賽]巧克力棒 博弈+模擬