zoukankan      html  css  js  c++  java
  • HDU 1536 S-Nim SG博弈

    S-Nim

    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
     
     
    题意:
      给你k个数 s[i]
      再给你m个询问,每次询问是一个nim游戏,但是相比nim不同的是,每次只能从各个堆中选取 s[i]的值除去
    题解
      SG函数的应用
      对于给定的k个数,我们预处理出sg[i]
      那么就简单了
      
    #include <iostream>
    #include <cstdio>
    #include <cmath>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    #pragma comment(linker, "/STACK:102400000,102400000")
    #define ls i<<1
    #define rs ls | 1
    #define mid ((ll+rr)>>1)
    #define pii pair<int,int>
    #define MP make_pair
    typedef long long LL;
    const long long INF = 1e18+1LL;
    const double Pi = acos(-1.0);
    const int N = 5e5+10, M = 2e5+20, mod = 1e9+7, inf = 2e9;
    
    int k,sg[N],s[N],vis[N];
    char A[N];
    int main() {
            while(scanf("%d",&k)!=EOF) {
                if(k == 0) break;
                for(int i = 1; i <= k; ++i) scanf("%d",&s[i]);
                sg[0] = 0;
                for(int i = 1; i <= 10000; ++i) {
                    for(int j = 0; j <= 100; ++j) vis[j] = 0;
                    for(int j = 1; j <= k; ++j) {
                       if(i >= s[j] && sg[i - s[j]] <= 100) vis[sg[i - s[j]]] = 1;
                    }
                    for(int j = 0; j <= 100; ++j) {
                        if(!vis[j]) {
                            sg[i] = j;
                            break;
                        }
                    }
                }
                int q,cnt = 0;
                scanf("%d",&q);
                while(q--) {
                    int x,y,ans = 0;
                    scanf("%d",&x);
                    while(x--) {
                        scanf("%d",&y);
                        ans ^= sg[y];
                    }
                    if(ans) printf("W");
                    else printf("L");
                }
                printf("
    ");
            }
        return 0;
    }
  • 相关阅读:
    CAS单点登录(一)——初识SSO
    Sql Server 增加字段、修改字段、修改类型、修改默认值
    SQL 聚合函数-非聚合函数
    漫画:什么是中台?
    windows下nginx的安装及使用
    sql优化点
    如何处理sql中的关键字(例如',%)
    Mysql 如何创建一张临时表
    MySQL中information_schema是什么
    mysql查看表结构命令,如下:
  • 原文地址:https://www.cnblogs.com/zxhl/p/6011128.html
Copyright © 2011-2022 走看看