zoukankan      html  css  js  c++  java
  • sg函数模板

    hdu1536:

    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
     
    #include<iostream>
    #include<stdio.h>
    #include<algorithm>
    #include<string.h>
    using namespace std;
    typedef long long ll;
    const int inf=0x3f3f3f3f;
    const int maxn=10010;
    int sg[maxn],s[maxn],k;
    bool vis[maxn];
    
    
    
    void SG(int n){
        memset(sg,0,sizeof(sg));
        for(int i=1;i<maxn;i++){
            memset(vis,false,sizeof(vis));
            for(int j=0;j<n&&s[j]<=i;j++) 
                vis[sg[i-s[j]]]=1;
            for(int j=0;j<maxn;j++){
                if(!vis[j]){
                    sg[i]=j;
                    break;
                }
            }
        }
    }
    
    
    
    
    
    
    
    int main(){
        int m,l,x;
        while(~scanf("%d",&k)){
            if(k==0) break;
            for(int i=0;i<k;i++)
            scanf("%d",&s[i]);
            sort(s,s+k);
            SG(k);
            scanf("%d",&m);
            while(m--){
                scanf("%d",&l);
                int sum=0;
                while(l--){
                    scanf("%d",&x);
                    sum^=sg[x];
                }
                if(sum==0)
                    printf("L");
                else 
                    printf("W");
            }
                printf("
    ");
        }    
    } 

    1847

    大学英语四级考试就要来临了,你是不是在紧张的复习?也许紧张得连短学期的ACM都没工夫练习了,反正我知道的Kiki和Cici都是如此。当然,作为在考场浸润了十几载的当代大学生,Kiki和Cici更懂得考前的放松,所谓“张弛有道”就是这个意思。这不,Kiki和Cici在每天晚上休息之前都要玩一会儿扑克牌以放松神经。
    “升级”?“双扣”?“红五”?还是“斗地主”?
    当然都不是!那多俗啊~
    作为计算机学院的学生,Kiki和Cici打牌的时候可没忘记专业,她们打牌的规则是这样的:
    1、  总共n张牌;
    2、  双方轮流抓牌;
    3、  每人每次抓牌的个数只能是2的幂次(即:1,2,4,8,16…)
    4、  抓完牌,胜负结果也出来了:最后抓完牌的人为胜者;
    假设Kiki和Cici都是足够聪明(其实不用假设,哪有不聪明的学生~),并且每次都是Kiki先抓牌,请问谁能赢呢?
    当然,打牌无论谁赢都问题不大,重要的是马上到来的CET-4能有好的状态。

    Good luck in CET-4 everybody!
     
    Input
    输入数据包含多个测试用例,每个测试用例占一行,包含一个整数n(1<=n<=1000)。
     
    Output
    如果Kiki能赢的话,请输出“Kiki”,否则请输出“Cici”,每个实例的输出占一行。
     
    Sample Input
    1 3
     
    Sample Output
    Kiki Cici
     
    Author
    lcy
     
    Source
     
    Recommend
    lcy   |   We have carefully selected several similar problems for you:  1849 1846 1850 2147 2149
     
    #include<iostream>
    #include<stdio.h>
    #include<algorithm>
    #include<string.h>
    using namespace std;
    typedef long long ll;
    const int inf=0x3f3f3f3f;
    const int maxn=10010;
    int sg[maxn],s[maxn],k;
    bool vis[maxn];
    
    
    
    void SG(int n){
        memset(sg,0,sizeof(sg));
        for(int i=1;i<maxn;i++){
            memset(vis,false,sizeof(vis));
            for(int j=0;j<n&&s[j]<=i;j++) 
                vis[sg[i-s[j]]]=1;
            for(int j=0;j<maxn;j++){
                if(!vis[j]){
                    sg[i]=j;
                    break;
                }
            }
        }
    }
    
    
    
    
    
    
    
    int main(){
        int m,l,x;
            int i;
            for(i=0;(1<<i)<=1000;i++){
                s[i]=1<<i;
            }
            SG(i);    
        while(~scanf("%d",&k)){
            int sum=0^sg[k];
            if(sg[k]==0) printf("Cici
    ");
            else printf("Kiki
    ");
        }    
    } 

    1848

    任何一个大学生对菲波那契数列(Fibonacci numbers)应该都不会陌生,它是这样定义的:
    F(1)=1;
    F(2)=2;
    F(n)=F(n-1)+F(n-2)(n>=3);
    所以,1,2,3,5,8,13……就是菲波那契数列。
    在HDOJ上有不少相关的题目,比如1005 Fibonacci again就是曾经的浙江省赛题。
    今天,又一个关于Fibonacci的题目出现了,它是一个小游戏,定义如下:
    1、  这是一个二人游戏;
    2、  一共有3堆石子,数量分别是m, n, p个;
    3、  两人轮流走;
    4、  每走一步可以选择任意一堆石子,然后取走f个;
    5、  f只能是菲波那契数列中的元素(即每次只能取1,2,3,5,8…等数量);
    6、  最先取光所有石子的人为胜者;

    假设双方都使用最优策略,请判断先手的人会赢还是后手的人会赢。
     
    Input
    输入数据包含多个测试用例,每个测试用例占一行,包含3个整数m,n,p(1<=m,n,p<=1000)。
    m=n=p=0则表示输入结束。
     
    Output
    如果先手的人能赢,请输出“Fibo”,否则请输出“Nacci”,每个实例的输出占一行。
     
    Sample Input
    1 1 1 1 4 1 0 0 0
     
    Sample Output
    Fibo Nacci
     
    Author
    lcy
     
    Source
     
    Recommend
    lcy   |   We have carefully selected several similar problems for you:  1850 1849 1846 2147 2149
     
    #include<iostream>
    #include<stdio.h>
    #include<algorithm>
    #include<string.h>
    using namespace std;
    typedef long long ll;
    const int inf=0x3f3f3f3f;
    const int maxn=1010;
    int sg[maxn],s[maxn],k;
    bool vis[maxn];
    
    
    
    void SG(int n){
        memset(sg,0,sizeof(sg));
        for(int i=1;i<maxn;i++){
            memset(vis,false,sizeof(vis));
            for(int j=0;j<n&&s[j]<=i;j++) 
                vis[sg[i-s[j]]]=1;
            for(int j=0;j<maxn;j++){
                if(!vis[j]){
                    sg[i]=j;
                    break;
                }
            }
        }
    }
    
    
    
    
    
    
    
    int main(){
        int m,n,p;
        s[0]=1;
        s[1]=2;
        int i;
        for(i=2;s[i-1]+s[i-2]<=1000;i++) s[i]=s[i-1]+s[i-2];
        SG(i);
        while(~scanf("%d%d%d",&m,&n,&p)){
            if(m==0&&n==0&&p==0) break;
            int sum=0^sg[m]^sg[n]^sg[p];
            if(sum==0) printf("Nacci
    ");
            else printf("Fibo
    ");
        }    
    } 
  • 相关阅读:
    CCF CSP 题解
    CCF CSP 2019032 二十四点
    CCF CSP 2018121 小明上学
    CCF CSP 2019092 小明种苹果(续)
    CCF CSP 2019091 小明种苹果
    CCF CSP 2019121 报数
    CCF CSP 2019031 小中大
    CCF CSP 2020061 线性分类器
    CCF CSP 2020062 稀疏向量
    利用国家气象局的webservice查询天气预报(转载)
  • 原文地址:https://www.cnblogs.com/ellery/p/11672284.html
Copyright © 2011-2022 走看看