zoukankan      html  css  js  c++  java
  • UVALive 7278 Game of Cards (sg函数)

    Game of Cards

    题目链接:

    http://acm.hust.edu.cn/vjudge/contest/127406#problem/G

    Description

    ``` Alice and Bob created a new game while at the beach this summer. All they need is a set of numbered playing cards. They start by creating P piles with all cards face-up and select a non-negative number K. After that, they take turns like this: 1. A player starts by selecting one of the piles. 2. Then, he removes from 0 up to K cards from the top of that pile, leaving at least one card in the pile. 3. Next, he looks at the card left at the top of the pile and must remove a number of cards equal to its value (from the top of the same pile). Whoever doesn’t have more cards to remove, or whoever is forced to remove more cards than those available on a pile, loses the game. In the figure, you can see an example with two piles and K = 1. The player to move might: a) Select the first pile and 0 cards to remove, being forced to remove 1 card from the top next. b) Select the second pile and 0 cards to remove, having to remove 1 card from the top next. c) Select the second pile and 1 card to remove, having to remove 2 cards from the top next. Alice has realized that Bob is very good at this game and will always win if he has the chance. Luckily, this time Alice is first to play. Is Alice able to win this game? Given the description of the piles with all the cards and the maximum number of cards they can start to remove, your goal is to find out whether Alice can win the game if she is the first to play. ```

    Input

    The input file contains several test cases, each of them as described below. The first line contains 2 space separated integers, P, the number of piles, and K, the maximum number of cards they can start to remove on their turn. The next P lines start with an integer N, indicating the number of cards on a pile. N space separated integers follow, representing the cards on that pile from the bottom to the top. Constraints: 1 ≤ P ≤ 100 Number of piles. 1 ≤ K ≤ 10 Maximum number of cards a player can start to remove. 1 ≤ c ≤ 10 Number on each card. 1 ≤ N ≤ 1 000 Size of each pile.

    Output

    For each test case, a single string, stating ‘Alice can win.’ or ‘Bob will win.’, as appropriate. Notes: Explanation of output 1. The piles are the same, so Bob will always be able to mirror whatever move Alice makes. Explanation of output 2. Alice can start by removing 0 cards from the second pile and then 1 card from its top. Two legal moves will be possible next, Bob will make one and Alice the other.

    Sample Input

    4 1 4 1 1 1 1 6 2 1 2 1 2 1 4 1 1 1 1 6 2 1 2 1 2 1 2 1 1 1 3 1 2 1 2 2 5 3 2 1 2 1 5 5 4 3 2 1

    Sample Output

    Bob will win. Alice can win. Alice can win.
    ##题意: 有n堆牌,每回合可以从一堆中先抽[0,k]张牌,但是这一抽后必须使得这一堆非空. 然后看牌堆顶的数字,再抽这么多的牌. 不能操作者输.
    ##题解: 典型的sg函数. 单独考虑每一堆. 以长度为牌堆的状态. sg[x] 表示牌堆中后x张牌的sg值. 对于每个状态,枚举取的个数[0,k]来得到拓展状态. 对于不可达到的状态,这里可以将其sg值设为-1. (如果后继状态都是-1那当前状态为0,即必败).
    ##代码: ``` cpp #include #include #include #include #include #include #include #include #include #include #include #define LL long long #define eps 1e-8 #define maxn 1010 #define mod 100000007 #define inf 0x3f3f3f3f #define mid(a,b) ((a+b)>>1) #define IN freopen("in.txt","r",stdin); using namespace std;

    int p,k;
    int sg[maxn];
    bool vis[maxn];
    int pile[maxn], cnt;

    int sg_check(int size, int take) {
    int top = pile[size - take];
    if(take + top > size) return -1;
    return sg[size-take-top];
    }

    void get_sg() {
    memset(sg, 0, sizeof(sg));

    for(int i=1; i<=cnt; i++) {
        /*误把初始化放到外面导致WA一发*/
        memset(vis, 0, sizeof(vis));
        for(int j=0; j<=k&&j<i; j++) {
            int tmp = sg_check(i, j);
            if(tmp != -1) vis[tmp] = 1;
        }
        for(int j=0; j<maxn; j++) if(!vis[j]) {
            sg[i] = j; break;
        }
    }
    

    }

    int main(int argc, char const *argv[])
    {
    //IN;

    while(scanf("%d %d", &p,&k) != EOF)
    {
        int ans = 0;
        while(p--) {
            scanf("%d", &cnt);
            for(int i=1; i<=cnt; i++)
                scanf("%d", &pile[i]);
            get_sg();
            ans ^= sg[cnt];
        }
    
        if(ans) puts("Alice can win.");
        else puts("Bob will win.");
    }
    
    return 0;
    

    }

  • 相关阅读:
    JS和C# 里的闭包及闭包在事件中的使用
    ***项目开发记录
    七牛云存储之应用视频上传系统开心得
    二维码及二维码接合短URL的应用
    EF批量添加,删除,修改的扩展
    ngTemplateOutlet递归的问题
    每日新知2019-06-03
    Spring boot初始
    纯前端播放本地音乐
    macbook 安装任意来源
  • 原文地址:https://www.cnblogs.com/Sunshine-tcf/p/5769055.html
Copyright © 2011-2022 走看看