• hdu 1536/ hdu 1944 S-Nim(sg函数)


    S-Nim

    Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
    Total Submission(s): 7751    Accepted Submission(s): 3266


    Problem Description
    Arthur and his sister Caroll have been playing a game called Nim for some time now. Nim is played as follows:


      The starting position has a number of heaps, all containing some, not necessarily equal, number of beads.

      The players take turns chosing a heap and removing a positive number of beads from it.

      The first player not able to make a move, loses.


    Arthur and Caroll really enjoyed playing this simple game until they recently learned an easy way to always be able to find the best move:


      Xor the number of beads in the heaps in the current position (i.e. if we have 2, 4 and 7 the xor-sum will be 1 as 2 xor 4 xor 7 = 1).

      If the xor-sum is 0, too bad, you will lose.

      Otherwise, move such that the xor-sum becomes 0. This is always possible.


    It is quite easy to convince oneself that this works. Consider these facts:

      The player that takes the last bead wins.

      After the winning player's last move the xor-sum will be 0.

      The xor-sum will change after every move.


    Which means that if you make sure that the xor-sum always is 0 when you have made your move, your opponent will never be able to win, and, thus, you will win. 

    Understandibly it is no fun to play a game when both players know how to play perfectly (ignorance is bliss). Fourtunately, Arthur and Caroll soon came up with a similar game, S-Nim, that seemed to solve this problem. Each player is now only allowed to remove a number of beads in some predefined set S, e.g. if we have S =(2, 5) each player is only allowed to remove 2 or 5 beads. Now it is not always possible to make the xor-sum 0 and, thus, the strategy above is useless. Or is it? 

    your job is to write a program that determines if a position of S-Nim is a losing or a winning position. A position is a winning position if there is at least one move to a losing position. A position is a losing position if there are no moves to a losing position. This means, as expected, that a position with no legal moves is a losing position.
     
    Input
    Input consists of a number of test cases. For each test case: The first line contains a number k (0 < k ≤ 100 describing the size of S, followed by k numbers si (0 < si ≤ 10000) describing S. The second line contains a number m (0 < m ≤ 100) describing the number of positions to evaluate. The next m lines each contain a number l (0 < l ≤ 100) describing the number of heaps and l numbers hi (0 ≤ hi ≤ 10000) describing the number of beads in the heaps. The last test case is followed by a 0 on a line of its own.
     
    Output
    For each position: If the described position is a winning position print a 'W'.If the described position is a losing position print an 'L'. Print a newline after each test case.
     
    Sample Input
    2 2 5 3 2 5 12 3 2 4 7 4 2 3 7 12 5 1 2 3 4 5 3 2 5 12 3 2 4 7 4 2 3 7 12 0
     
    Sample Output
    LWW WWL
     
    Source
     
     

    题意:首先输入K 表示一个集合的大小  之后输入集合 表示对于这对石子只能去这个集合中的元素的个数

    之后输入 一个m 表示接下来对于这个集合要进行m次询问 

    之后m行 每行输入一个n 表示有n个堆  每堆有n1个石子  问这一行所表示的状态是赢还是输 如果赢输入W否则L

    思路:对于n堆石子 可以分成n个游戏 之后把n个游戏合起来就好了
     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 const int MAXN = 100 + 5;
     5 const int MAXM = 10000 + 5;
     6 
     7 int f[MAXN];//f[0]存合法移动个数
     8 int sg[MAXM];
     9 bool exist[MAXN];//hash, sg不会超过合法移动个数MAXN
    10 
    11 void getSg(int n)
    12 {
    13     int i, j;
    14     sg[0] = 0;
    15     for (i = 1; i <= n; ++i) {
    16         memset(exist, false, sizeof(exist));
    17         for (j = 1; j <= f[0] && f[j] <= i; ++j) {
    18             exist[sg[i - f[j]]] = true;
    19         }
    20         for (j = 0; j < MAXN; ++j) {
    21             if (!exist[j]) {
    22                 sg[i] = j;
    23                 break;
    24             }
    25         }
    26     }
    27 }
    28 
    29 
    30 int main()
    31 {
    32     int k;//, s;
    33     int m;
    34     int l, hi;
    35     int i, j;
    36     int sum;
    37 
    38     while (~scanf("%d", &k)) {
    39         if (k == 0) {
    40             break;
    41         }
    42         f[0] = k;
    43         for (i = 1; i <= k; ++i) {
    44             scanf("%d", &f[i]);
    45         }
    46         sort(f + 1, f + 1 + k);
    47         getSg(10000);
    48 
    49         scanf("%d", &m);
    50         for (i = 0; i < m; ++i) {
    51             scanf("%d", &l);
    52             sum = 0;
    53             for (j = 0; j < l; ++j) {
    54                 scanf("%d", &hi);
    55                 sum ^= sg[hi];
    56             }
    57             if (sum != 0) {
    58                 printf("W");
    59             } else {
    60                 printf("L");
    61             }
    62         }
    63         printf("
    ");
    64 
    65     }
    66     return 0;
    67 }
    View Code
     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 const int MAXN = 100 + 5;
     5 const int MAXM = 10000 + 5;
     6 
     7 int s[MAXN];
     8 int sg[MAXM];
     9 int n;//s中的个数
    10 
    11 int dfsSg(int x)
    12 {
    13     if (sg[x] != -1) {
    14         return sg[x];
    15     }
    16     int i;
    17     bool vis[MAXN];//sg范围
    18     memset(vis, false, sizeof(vis));
    19     for (i = 0; i < n && s[i] <= x; ++i) {
    20         dfsSg(x - s[i]);
    21         vis[sg[x - s[i]]] = true;
    22     }
    23     for (i = 0; i <= x; ++i) {
    24         if (!vis[i]) {
    25             sg[x] = i;
    26             break;
    27         }
    28     }
    29     return sg[x];
    30 }
    31 
    32 
    33 int main()
    34 {
    35     int k;//, s;
    36     int m;
    37     int l, hi;
    38     int i, j;
    39     int sum;
    40 
    41     while (~scanf("%d", &k)) {
    42         if (k == 0) {
    43             break;
    44         }
    45         n = k;
    46         for (i = 0; i < k; ++i) {
    47             scanf("%d", &s[i]);
    48         }
    49         sort(s, s + k);
    50         memset(sg, -1, sizeof(sg));
    51         scanf("%d", &m);
    52         for (i = 0; i < m; ++i) {
    53             scanf("%d", &l);
    54             sum = 0;
    55             for (j = 0; j < l; ++j) {
    56                 scanf("%d", &hi);
    57                 sum ^= dfsSg(hi);
    58             }
    59             if (sum != 0) {
    60                 printf("W");
    61             } else {
    62                 printf("L");
    63             }
    64         }
    65         printf("
    ");
    66 
    67     }
    68     return 0;
    69 }
    View Code
  • 相关阅读:
    动态获取Resources里面的图片列表
    在LINQ中实现多条件联合主键LEFT JOIN
    Failed to fetch URL http://dlssl.google.com/android/repository/repository.xml
    LINQ多条件OR模糊查询
    使用ILMerge将所有引用的DLL和exe文件打成一个exe文件
    安卓模拟器、电脑运行安卓系统android、apk文件
    C/C++中枚举类型(enum)
    指针详解
    Visaul Studio 2008 中配置DirectX9c的开发环境
    出自涅磐,缘自凤凰
  • 原文地址:https://www.cnblogs.com/gongpixin/p/6780304.html
Copyright © 2020-2023  润新知