• HDU 1535 S-Nim(SG函数)


    S-Nim

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


    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,表示有几种每次取石子个数的集合,即给出123,每次可以取1,2,3个。然后给出询问次数m。每次询问给出n堆石子,然后询问当前状态是P还是N。

    分析

    SG函数。两种求法,都写了一遍。耗时间差不多

    code

    预处理

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 
     5 using namespace std;
     6 
     7 const int N = 10000;
     8 int sg[10100],f[1010];
     9 int k,n,m;
    10 bool Hash[1010];
    11 
    12 void get_SG() {
    13     memset(sg,0,sizeof(sg));
    14     for (int i=1; i<=N; ++i) {
    15         memset(Hash,false,sizeof(Hash));
    16         for (int j=1; j<=k&&f[j]<=i; ++j) 
    17             Hash[sg[i-f[j]]] = true;
    18         for (int j=0; j<=N; ++j) 
    19             if (!Hash[j]) {sg[i] = j;break;}        
    20     }
    21 }
    22 
    23 int main () {
    24     while (~scanf("%d",&k) && k) {
    25         for (int i=1; i<=k; ++i) 
    26             scanf("%d",&f[i]);
    27         sort(f+1,f+k+1);
    28         get_SG();
    29         scanf("%d",&m);
    30         for (int i=1; i<=m; ++i) {
    31             scanf("%d",&n);
    32             int ans = 0;
    33             for (int t,j=1; j<=n; ++j) {
    34                 scanf("%d",&t);
    35                 ans ^= sg[t];
    36             }
    37             if (ans == 0) printf("L");
    38             else printf("W");
    39         }
    40         puts("");
    41     }
    42     return 0;
    43 }
    View Code

    dfs记忆化搜索

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 using namespace std;
     5 
     6 int sg[10100],f[1010];
     7 int k,n,m;
     8 
     9 int get_SG(int x) {
    10     if (sg[x] != -1) return sg[x];
    11     bool Hash[110]; //不能再外面开 
    12     memset(Hash,false,sizeof(Hash));
    13     for (int i=1; i<=k; ++i) {
    14         if (f[i] > x) break;
    15         get_SG(x-f[i]);
    16         Hash[sg[x-f[i]]] = true;
    17     }
    18     for (int i=0; ; ++i) 
    19         if (!Hash[i]) {sg[x] = i;break;}
    20     return sg[x];
    21 }
    22 int main () {
    23     while (~scanf("%d",&k) && k) {
    24         for (int i=1; i<=k; ++i) 
    25             scanf("%d",&f[i]);
    26         sort(f+1,f+k+1);
    27         memset(sg,-1,sizeof(sg));
    28         sg[0] = 0;
    29         scanf("%d",&m);
    30         for (int i=1; i<=m; ++i) {
    31             scanf("%d",&n);
    32             int ans = 0;
    33             for (int t,j=1; j<=n; ++j) {
    34                 scanf("%d",&t);
    35                 ans ^= get_SG(t);
    36             }
    37             if (ans == 0) printf("L");
    38             else printf("W");
    39         }
    40         puts("");
    41     }
    42     return 0;
    43 }
    View Code
  • 相关阅读:
    Spring Boot2 系列教程(二)创建 Spring Boot 项目的三种方式
    Spring Boot2 系列教程(一)纯 Java 搭建 SSM 项目
    Python 解析XML实例(xml.sax)
    深度学习Tensorflow相关书籍推荐和PDF下载
    气象netCDF数据可视化分析
    Python 操作MySQL 数据库
    用这个库 3 分钟实现让你满意的表格功能:Bootstrap-Table
    浅谈压缩感知(二十六):压缩感知重构算法之分段弱正交匹配追踪(SWOMP)...
    web开发工具flask中文英文书籍-持续更新
    Python 在气象上的应用
  • 原文地址:https://www.cnblogs.com/mjtcn/p/8481074.html
Copyright © 2020-2023  润新知