zoukankan      html  css  js  c++  java
  • HDU 5724 Chess(SG函数)

    Chess

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
    Total Submission(s): 2605    Accepted Submission(s): 1092


    Problem Description
    Alice and Bob are playing a special chess game on an n × 20 chessboard. There are several chesses on the chessboard. They can move one chess in one turn. If there are no other chesses on the right adjacent block of the moved chess, move the chess to its right adjacent block. Otherwise, skip over these chesses and move to the right adjacent block of them. Two chesses can’t be placed at one block and no chess can be placed out of the chessboard. When someone can’t move any chess during his/her turn, he/she will lose the game. Alice always take the first turn. Both Alice and Bob will play the game with the best strategy. Alice wants to know if she can win the game.
     
    Input
    Multiple test cases.

    The first line contains an integer T(T100) , indicates the number of test cases.

    For each test case, the first line contains a single integer n(n1000) , the number of lines of chessboard.

    Then n lines, the first integer of ith line is m(m20) , indicates the number of chesses on the ith line of the chessboard. Then m integers pj(1pj20) followed, the position of each chess.
     
    Output
    For each test case, output one line of “YES” if Alice can win the game, “NO” otherwise.
     
    Sample Input
    2 1 2 19 20 2 1 19 1 18
     
    Sample Output
    NO YES
     
    解题思路:
      此题相较一般的组合博弈规则上有所不同,无法使用一般的Nim博弈、威佐夫博弈那样直接用公式进行推导而取得结果,所以一般使用SG函数来处理此类问题,而此题由于状态相对单一(即一个点只有有棋子和没有棋子两种状态),故可用一bit来表示在一行中一个点有没有棋子,有棋子为1,没有棋子为0,因为每一行的棋子数量不定,故有可能一行20个位置都是棋子为了表示这种的不同的情况,进行状态压缩,用一个int来表示这种情况显然是更好的选择。其中int i=1即代表一行只有一个棋子,而此棋子在最右边的情况,0到(2^20-1)就代表全了所有的可能,存于SG中,之后读取并Nim博弈的异或看结果就好了。
     
    代码:
     1 #include <iostream>
     2 #include <cstdio>
     3 #include <algorithm>
     4 #include <cstdlib>
     5 #include <cstring>
     6 #include <cmath>
     7 using namespace std;
     8 int sg[(1<<20)+1000];
     9 int main(){
    10 
    11 
    12     for(int i = 1;i < (1<<20); i++){
    13         int h[25];
    14         memset(h, -1, sizeof(h));
    15         int last = -1;
    16         for(int j = 0; j < 20; j++){
    17 
    18             if(!((i >> j) & 1))
    19                 last = j;
    20             if(((i >> j) & 1)){
    21                 if(last != -1){
    22                     h[sg[(i ^ (1 << j)) ^ (1 << last)]]=1;
    23                 }
    24             }
    25         }
    26         int j=0;
    27         while(h[j] != -1) j++;
    28         sg[i]=j;
    29     }
    30     int T;
    31     scanf("%d", &T);
    32     while(T--){
    33         int n, tmp, m, ans=0;
    34         scanf("%d", &n);
    35         for(int i = 1; i <= n; i++){
    36             scanf("%d", &m);
    37             tmp = 0;
    38             for(int j = 1; j <= m; j++){
    39                 int x;
    40                 scanf("%d", &x);
    41                 tmp ^= 1 << (20 - x);
    42             }
    43             ans ^= sg[tmp];
    44 
    45         }
    46         if(ans)
    47             puts("YES");
    48         else
    49             puts("NO");
    50     }
    51 }
     
     
  • 相关阅读:
    在ASP.NET应用程序中使用身份模拟(Impersonation)
    在VS项目中使用SVN版本号作为编译版本号
    android学习网站
    RFID:ISO14443、15693、18000体系分析
    android-custom-tab-with-viewpager
    DoubleViewPager
    RecyclerViewDemo
    FragmentSharedFabTransition
    Material-Animations
    MaterialImageLoading
  • 原文地址:https://www.cnblogs.com/87hbteo/p/7124484.html
Copyright © 2011-2022 走看看