zoukankan      html  css  js  c++  java
  • poj-2960 S-Nim

    S-Nim
    Time Limit: 2000MS   Memory Limit: 65536K
    Total Submissions: 3891   Accepted: 2037

    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

    题目大意:给出n堆石子,两人轮流在任意一堆里可以取出s[i]个石子,直到对方不能取,你获胜,否则对方获胜,游戏结束

    基础博弈,sg函数模板,但是要先计算出大概11000内的sg,否则会RE,TLE

    sg函数:sg(n) = min( N – {sg(n-1), sg(n-2), …sg(n-m)} )

    二维sg函数的异或sg(<n1, n2>) = sg(n1)^sg(n2)

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<string>
     4 #include<map>
     5 #include<cstring>
     6 #include<algorithm>
     7 using namespace std;
     8 int s[11000], k;
     9 int SG[11000];
    10 int sg(int n){
    11     int a[11000], i, j;
    12     memset(a, 0, sizeof(a));
    13    // SG[0] = 0;
    14     for(i=1; i<=k; i++){
    15         if(n-s[i] >= 0){
    16             //printf("----%d
    ",SG[n-s[i]]);
    17             a[SG[n-s[i]]] = 1;
    18         }
    19     }
    20     for(i=0; i<=1100; i++){
    21         if(!a[i]){
    22             //printf("  %d
    ",i);
    23             return i;
    24         }
    25     }
    26 }
    27 int main(){
    28     int m, n, a, i, j;
    29     int l;
    30     char ch[11000];
    31     while(cin>>k && k){
    32         for(i=1; i<=k; i++)
    33             cin>>s[i];
    34         //sg[0] = 0;
    35         cin>>m;
    36         SG[0]=0;
    37         for(int h=1; h<=11000; h++){
    38             SG[h] = sg(h);//sg(n) = min( N – {sg(n-1), sg(n-2), …sg(n-m)} )
    39         }
    40         for(l=0; l<m; l++){
    41             cin>>a;
    42             int sum=0;
    43             for(i=0; i<a; i++){
    44                 cin>>n;
    45                 //printf("  %d
    ",SG[n]);
    46                 sum = sum^SG[n];//sg(5) sg(12)
    47             }
    48             if(sum==0)
    49                 ch[l] = 'L';//异或结果为0则输
    50             else
    51                 ch[l] = 'W';//异或结果不为0则赢
    52         }
    53         ch[l]='';
    54         printf("%s
    ",ch);
    55     }
    56     return 0;
    57 }
  • 相关阅读:
    x64 平台开发 Mapxtreme 编译错误
    hdu 4305 Lightning
    Ural 1627 Join(生成树计数)
    poj 2104 Kth Number(可持久化线段树)
    ural 1651 Shortest Subchain
    hdu 4351 Digital root
    hdu 3221 Bruteforce Algorithm
    poj 2892 Tunnel Warfare (Splay Tree instead of Segment Tree)
    hdu 4031 Attack(BIT)
    LightOJ 1277 Looking for a Subsequence
  • 原文地址:https://www.cnblogs.com/wudi-accept/p/5510147.html
Copyright © 2011-2022 走看看