LightOJ 1344 Aladdin and the Game of Bracelets

It's said that Aladdin had to solve seven mysteries before getting the Magical Lamp which summons a powerful Genie. Here we are concerned about the fourth mystery.

In the cave, Aladdin was moving forward after passing the pathway of magical stones. He found a door and he was about to open the door, but suddenly a Genie appeared and he addressed himself as the guardian of the door. He challenged Aladdin to play a game and promised that he would let Aladdin go through the door, if Aladdin can defeat the Genie. Aladdin defeated the Genie and continued his journey. However, let's concentrate on the game.

The game was called 'Game of Bracelets'. A bracelet is a linear chain of some pearls of various weights. The rules of the game are:

1)      There are n bracelets.

2)      Players alternate turns.

3)      In each turn, a player has to choose a pearl from any bracelet. Then all the pearls from that bracelet, that werenot lighter than the pearl, will be removed. It may create some smaller bracelets or the bracelet will be removed if no pearl is left in the bracelet.

4)      The player, who cannot take a pearl in his turn, loses.

For example, two bracelets are: 5-1-7-2-4-5-3 and 2-1-5-3, here the integers denote the weights of the pearls. Suppose a player has chosen the first pearl (weight 5) from the first bracelet. Then all the pearls that are not lighter than 5, will be removed (from first bracelet). So, 5-1-7-2-4-5-3, the red ones will be removed and thus from this bracelet, three new bracelets will be formed, 1, 2-4 and 3. So, in the next turn the other player will have four bracelets: 1, 2-4, 3 and 2-1-5-3. Now if a player chooses the only pearl (weight 3) from the third bracelet, then the bracelet will be removed.

Now you are given the information of the bracelets. Assume that Aladdin plays first, and Aladdin and the Genie both play optimally. Your task is to find the winner.

Input

Input starts with an integer T (≤ 50), denoting the number of test cases.

Each case starts with a line containing an integer n (1 ≤ n ≤ 50). Each of the next n lines contains an integer Ki (1 ≤ Ki ≤ 50) followed by Ki integers, denoting the weights of the pearls of the ith (1 ≤ i ≤ n) bracelet. Each weight will lie in the range [1, 105].

Output

For each case, print the case number and 'Aladdin' if Aladdin wins. Otherwise print 'Genie'. If Aladdin wins, then print an additional line, denoting the weight of pearls, one of which should be chosen in the first move by Aladdin such that he can win. Each pearl should be denoted by a pair of integers: the first integer is the bracelet number and the second integer is the weight. Sort the pearls first by the bracelet number then by the weight. And same weight in a bracelet should be reported once. Check the samples for exact formatting.

Sample Input

4

2

7 5 1 7 2 4 5 3

4 2 1 5 4

2

2 5 2

2 5 2

1

5 5 2 5 2 5

3

5 5 2 5 2 5

5 7 2 7 3 2

4 5 1 5 4

Sample Output

Case 1: Aladdin

(2 5)

Case 2: Genie

Case 3: Aladdin

(1 2)(1 5)

Case 4: Aladdin

(2 7)(3 1)(3 5)

题意:题目意思就是给你n串珍珠,没串珍珠有若干数量,现在两个人进行博弈;轮流进行操作;每次操作选择一个数,然后该珍珠里面大于等于该数的珍珠都会被拿走,此时,该珍珠会被分成其他几个珍珠;

最后谁不能拿,谁输;

题解:每个手镯都是独立的,因此可以异或每个手镯的 sg 值求解。而每个手镯,可以在某些结点被取走珠子,变成新的几段,任意一种情况的 sg 值,便是新分成的几段的 sg 值异或起来。再将每一种情况的 sg 值,记录在 vis 中,查找没出现过的最小的值,便是这个手镯的 sg 值。

参考代码:

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 const int maxn = 55;
  4 int sg[maxn][maxn]; 
  5 int arr[maxn][maxn], num[maxn];
  6 int sgtmp[maxn]; 
  7 int ret[maxn][maxn]; 
  8 
  9 struct node {
 10     int x, y;
 11 } output[maxn * maxn]; 
 12 bool operator==(node a,node b){return a.x==b.x&&arr[a.x][a.y]==arr[b.x][b.y];}
 13 bool cmp(node a,node b)
 14 {
 15     if(a.x==b.x) return arr[a.x][a.y]<arr[b.x][b.y];
 16     return a.x<b.x;
 17 }
 18 
 19 int dfs(int now,int l,int r)
 20  {
 21     if(l>r) return 0;
 22     if(l==r) return sg[l][r]=1; 
 23     if(sg[l][r]!=-1) return sg[l][r]; 
 24 
 25     int vis[maxn]; 
 26     memset(vis,0,sizeof(vis));
 27 
 28     for(int i=l;i<=r;++i) 
 29     {
 30         int tmp=0,last=-1;
 31 
 32         for(int j=l;j<=r;++j) 
 33         {
 34             if(arr[now][j]<arr[now][i]) 
 35             {
 36                 last = j;
 37                 break;
 38             }
 39         }
 40         
 41         for(int j = last + 1; j <= r && last != -1; ++j) 
 42         {
 43             if(arr[now][j] >= arr[now][i]) 
 44             {
 45                 tmp ^= dfs(now, last, j - 1);
 46                 last = -1;
 47                 for (int k = j + 1; k <= r; ++k) 
 48                 {
 49                     if (arr[now][k] < arr[now][i]) 
 50                     {
 51                         last = j = k;
 52                         break;
 53                     }
 54                 }
 55             }
 56         }
 57         if(last != -1) tmp ^= dfs(now, last, r);
 58         vis[tmp] = 1;
 59         if (l == 1 && r == num[now]) ret[now][i] = tmp;
 60     }
 61     
 62     for(int i = 0;;++i) 
 63     {
 64         if(vis[i]==0) 
 65         {
 66             sg[l][r]=i;
 67             return i;
 68         }
 69     }
 70 }
 71 
 72 int main() 
 73 {
 74     int t, k, ca = 1;
 75     scanf("%d", &t);
 76     while (t--) 
 77     {
 78         int ans = 0;
 79         scanf("%d", &k);
 80         for(int i = 1; i <= k; ++i) 
 81         {
 82             memset(sg, -1, sizeof(sg));
 83             scanf("%d", &num[i]);
 84             for(int j = 1; j <= num[i]; ++j) scanf("%d", &arr[i][j]);
 85  
 86             sgtmp[i] = dfs(i, 1, num[i]);
 87             ans ^= sgtmp[i];
 88         }
 89         if (ans == 0) printf("Case %d: Genie\n", ca++);
 90         else {
 91             int cnt = 0;
 92             printf("Case %d: Aladdin\n", ca++);
 93             memset(output, 0, sizeof(output));
 94             for (int i = 1; i <= k; ++i)
 95                 for (int j=1;j<=num[i];++j){if((ans^sgtmp[i]^ret[i][j])==0) output[cnt++] = {i, j};}
 96             sort(output,output+cnt,cmp);
 97             cnt=(int)(unique(output,output+cnt)-output);
 98             for(int i = 0; i < cnt; ++i) 
 99                 printf("(%d %d)", output[i].x, arr[output[i].x][output[i].y]);
100             printf("\n");
101         }
102     }
103     return 0;
104 }
View Code

 

posted @ 2019-03-13 16:48  StarHai  阅读(336)  评论(0编辑  收藏  举报