• USACO 作弊的发牌者


                作弊的发牌者

      

      贝茜正在与她的N-1(2 <= N <= 100)个朋友打牌。她们玩的牌一副为K(N <= K <= 100,000,K为N的倍数)张。所有牌中,一共有M(M = K / N)张“好牌”,其余的K - M张为“差牌”。贝茜是游戏的发牌者,很自然地,她想把所有好牌都留给自己。她热衷于获胜,即使为此必须采取一些不正当的手段。

      在若干局游戏后,贝茜的朋友们开始怀疑贝茜在游戏中作弊,于是她们想了个对策:使用新的发牌规则。规则具体如下:

      1. 贝茜把牌堆的最上面一张发给她右边的奶牛

      2. 每当贝茜发完一张牌,她都得将牌堆顶部接下来的P(1 <= P <= 10)张牌
    放到底部去(一般把这个操作称为切牌)

      3. 然后,贝茜对逆时针方向的下一头奶牛重复上述的操作

      贝茜绝望地认为,她再也不可能获胜了,于是她找到了你,希望你告诉她,将好牌放在初始牌堆的哪些位置,能够确保它们在发完牌后全集中到她手里。顺带说明一下,我们把牌堆顶的牌定义为1号牌,从上往下第二张定义为2号牌,依此类推。

    输入格式:

    第1行: 3个用空格隔开的整数:N、K,以及P

    输出格式:

    第1..M行: 每行输出一个正整数,表示贝茜应该在初始牌堆的这个位置放一张
    好牌。所有的位置按升序输出。

    样例输入:

    3 9 2

    样例输出:

    3
    7
    8

    输出说明:

      贝茜选择在牌堆中初始位置3、7、8各放一张好牌,这样她能在发完牌后如
    愿以偿地拿到所有的好牌。以下是对这场游戏的模拟,牌堆中的数字代表这张牌
    在初始牌堆中的位置:
                       牌堆        奶牛1     奶牛2     贝茜
    初始状态            1 2 3 4 5 6 7 8 9    - - -      - - -       - - -
    将牌堆顶的牌[1号牌]发给奶牛1  2 3 4 5 6 7 8 9  1 - -      - - -       - - -
    切牌(#1 of 2)            3 4 5 6 7 8 9 2  1 - -       - - -       - - -
    切牌(#2 of 2)            4 5 6 7 8 9 2 3  1 - -       - - -       - - -
    将牌堆顶的牌[4号牌]发给奶牛2  5 6 7 8 9 2 3     1 - -      4 - -       - - -
    切牌(#1 of 2)            6 7 8 9 2 3 5     1 - -      4 - -        - - -
    切牌(#2 of 2)            7 8 9 2 3 5 6     1 - -      4 - -        - - -
    将牌堆顶的牌[7号牌]发给贝茜   8 9 2 3 5 6    1 - -       4 - -       7 - -
    切牌(#1 of 2)            9 2 3 5 6 8    1 - -      4 - -        7 - -
    切牌(#2 of 2)            2 3 5 6 8 9    1 - -      4 - -        7 - -
    将牌堆顶的牌[2号牌]发给奶牛1  3 5 6 8 9      1 2 -      4 - -        7 - -
    切牌(#1 of 2)            5 6 8 9 3      1 2 -       4 - -        7 - -
    切牌(#2 of 2)            6 8 9 3 5      1 2 -       4 - -        7 - -
    将牌堆顶的牌[6号牌]发给奶牛2  8 9 3 5       1 2 -      4 6 -       7 - -
    切牌(#1 of 2)            9 3 5 8      1 2 -      4 6 -       7 - -
    切牌(#2 of 2)            3 5 8 9      1 2 -      4 6 -       7 - -
    将牌堆顶的牌[3号牌]发给贝茜   5 8 9         1 2 -      4 6 -       7 3 -
    切牌(#1 of 2)            8 9 5        1 2 -       4 6 -       7 3 -
    切牌(#2 of 2)            9 5 8         1 2 -      4 6 -       7 3 -
    将牌堆顶的牌[9号牌]发给奶牛1  5 8         1 2 9     4 6 -        7 3 -
    切牌(#1 of 2)            8 5         1 2 9     4 6 -        7 3 -
    切牌(#2 of 2)            5 8        1 2 9    4 6 -        7 3 -
    将牌堆顶的牌[5号牌]发给奶牛2  8         1 2 9     4 6 5        7 3 -
    切牌(#1 of 2)            8         1 2 9      4 6 5       7 3 -
    切牌(#2 of 2)            8         1 2 9      4 6 5       7 3 -
    将牌堆顶的牌[8号牌]发给贝茜    -         1 2 9      4 6 5       7 3 8

    发牌结束后,贝茜拿到了牌堆中初始位置分别为3、7、8的牌。

    题解

    嗯......为了练习静态链表,这道题使用了静态链表来写

    不过用队列的话代码好像要少一半

    然后就是模拟,发一次牌(删除一次),放p张到最后

    #include<iostream>
    #include<iomanip>
    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    #define MAX 20000010
    int n,k,p,sum,out[110000]={},top=0;
    
    struct QAQ
    {
        int data; 
        int cur;
    }s[MAX];
    
    void del()//删除第一个(发一次牌)(这里是直接更改s[0].cur指向下一位)
    {
        int temp=s[0].cur;
        s[0].cur=s[temp].cur;
    }
    
    void insert()//每次向后添加p个
    {
        s[top].data=s[s[0].cur-1].data;
        s[top].cur=top+1;
        s[0].cur++;
    }
    
    int main()
    {
        cin>>n>>k>>p;
        sum=k/n;
    
        for(int i=0;i<k;i++)
        {
            s[i].data=i+1;
            s[i].cur=i+1;
        }
        top=k;
        
        for(int i=1;i<=sum;i++)
        {
            for(int j=1;j<=n;j++)
            {
                
                del();
                for(int l=1;l<=p;l++)
                {
                    insert();
                    top++;
                }
                if(j==n-1)//记录下此时将要删除(发牌给自己)的值,即为答案
                    out[i]=s[s[0].cur-1].data;
            }
        }
        
        sort(out+1,out+sum+1);
        for(int i=1;i<=sum;i++)
            cout<<out[i]<<' ';
        
        return 0;
    }
  • 相关阅读:
    151. 翻转字符串里的单词(trim函数与split函数的使用)
    Java splt方法,按照空格分割字符串成为字符串数组(转载)
    137. 只出现一次的数字 II(没完全按要求做)
    129. 求根到叶子节点数字之和(递归
    125. 验证回文串(replaceAll()与toLowerCase())
    美团上海Java实习(已offer)面经(还没写完,转载)
    二叉树中序遍历
    优先队列/最大堆
    防御式编程
    JWT
  • 原文地址:https://www.cnblogs.com/kekit/p/6337035.html
Copyright © 2020-2023  润新知