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 }
  • 相关阅读:
    《Machine Learning in Action》—— 白话贝叶斯,“恰瓜群众”应该恰好瓜还是恰坏瓜
    《Machine Learning in Action》—— 女同学问Taoye,KNN应该怎么玩才能通关
    《Machine Learning in Action》—— Taoye给你讲讲决策树到底是支什么“鬼”
    深度学习炼丹术 —— Taoye不讲码德,又水文了,居然写感知器这么简单的内容
    《Machine Learning in Action》—— 浅谈线性回归的那些事
    《Machine Learning in Action》—— 懂的都懂,不懂的也能懂。非线性支持向量机
    《Machine Learning in Action》—— hao朋友,快来玩啊,决策树呦
    《Machine Learning in Action》—— 剖析支持向量机,优化SMO
    《Machine Learning in Action》—— 剖析支持向量机,单手狂撕线性SVM
    JVM 字节码指令
  • 原文地址:https://www.cnblogs.com/wudi-accept/p/5510147.html
Copyright © 2011-2022 走看看