ACM/ICPC 2018亚洲区预选赛北京赛站网络赛 C-cheat

超级水的模拟的,我也就会做模拟了……坑有点多,一直没调出来bug,赛后才发现少了一个数字……

描述
Cheat is a card game played by four players sitting around a table.
They are numbered from 1 to 4 in clockwise order.

A pack of 52 cards is used. There are 13 ranks from low to high: A, 2,
3, 4, 5, 6, 7, 8, 9, 10, J, Q, K, and four cards for each rank. At the
beginning, each player gets 13 cards in hand randomly. The first
player who discards all his cards is the winner.

The game consists of multiple rounds.

In each round: At first, a player, let’s call him as a “round holder”,
put down some face-down cards on the table and makes a statement about
the rank of those cards (such as “These are two Qs”) . In a statement,
all cards are of the same rank. Round holder can lie if he wants to.
Then, other players will decide whether to challenge the statement in
turn according to clockwise order. If nobody challenges, this round
ends and the cards remains on the table. If somebody challenges, the
cards put down by the round holder will be revealed. If the statement
is true, the challenger takes back all cards on the table, and this
round ends. If the statement is a lie, the round holder takes back all
cards on the table, and this round also ends.

Player 1 is the first round holder. And players take turns to be the
round holder according to clockwise order until someone wins. The
first round holder must state that the cards he put down on the table
are all rank A. Other statements must be exactly one rank higher than
the previous statement (But rank K is followed by rank A). If a round
holder has no cards of the required rank, he has to lie.

The first player who empty his hand at the end of a round is the
winner.

Assume players played with the following strategies:

Player 1:

  1. When being the round holder, he always makes a true statement and put down one card of the required rank if he can. If he can’t, he
    always put down one card with the minimum lexicographic rank order.
    (10<2<3<…<9<A<J<K<Q)

  2. Challenge the round holder if he is the next round holder and he has to lie in the next round.

  3. Challenge the round holder if the round holder states that he put down p cards of rank X, and player 1 has q cards of rank X in his
    hand, and p+q>4.

Player 2:

  1. When being the round holder, he always makes a true statement and put down all cards of the required rank if he can. If he can’t, he
    always put down one card with the minimum lexicographic rank order.
    (10<2<3<…<9<A<J<K<Q)

  2. Challenge the round holder if and only if he is the next round holder and he has to lie in the next round.

Player 3:

  1. When being the round holder, he always makes a true statement and put down all cards of the required rank if he can. If he can’t, he
    always put down all cards of a rank whose number of cards is the
    minimum in his hand. If there are multiple choices, choose the cards
    with the minimum lexicographic order. (10<2<3<…<9<A<J<K<Q)

  2. Challenge the statement if and only if he has all 4 cards of the stated rank in his hand.

Player 4:

  1. When being the round holder, always put down all cards of the required rank if he has three or four of them. Otherwise, always put
    down all cards of the required rank (if any) along with one more card
    (if any) with the minimum lexicographic order. (10<2<3<…<9<A<J<K<Q)

  2. Challenge the round holder if and only if the round holder has already emptied his hand.

Given the cards each player has at the beginning, could you please
figure out the cards in each player’s hand when the game ends?

输入
There are no more than 100 test cases.

For each test case:

Four lines, indicating the cards in player 1, 2, 3 and 4 respectively.

Each line contains 13 strings separated by white space, indicating the
rank of each card.

It is guaranteed that the given 52 cards form a pack.

输出
For each test case:

Output four lines, each line has multiple strings separated by white
space, indicating the cards in each player’s hand ordered by rank. The
line for the winner is “WINNER”. It is guaranteed that there are at
most 1000 rounds each game.

样例输入
A 2 3 4 5 6 7 8 9 10 J Q K
A 2 3 4 5 6 7 8 9 10 J Q K
A 2 3 4 5 67 8 9 10 J Q K
A 2 3 4 5 6 7 8 9 10 J Q K
K A A A 5 5 5 5 9 9 9 9 K
A 2 2 2 2 6 6 6 6 10 10 10 10
3 3 3 3 7 7 7 7 J J J J K
4 4 4 4 8 8 8 8 Q Q Q Q K
样例输出
2 6 7 10 J
3 7 8 J Q
4 8 9 Q K
WINNER
A A 5 5 5 9 9 9
K
WINNER
K A A 2 2 2 2 3 3 3 3 4 4 4 4 5 6 6 6 6 7 7 7 7 8 8 8 8 9 10 10 10 10 J J J J Q Q Q Q K K

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+7;
const ll mod=1e9+7;
int a[5][15]={0},desk[15]={0},minlex[15]={10,2,3,4,5,6,7,8,9,1,11,13,12};
char ma[15][3]={"A","2","3","4","5","6","7","8","9","10","J","Q","K"};
int statement(int h,int r,int& num)//返回说真话还是假话
{
    if(h==1){
        num=1;
        if(a[1][r%13==0?13:r%13]>0){
            desk[r%13==0?13:r%13]++;
            a[1][r%13==0?13:r%13]--;

            return 1;
        }
        else{
            for(int i=0;i<13;i++)
            {
                if(a[1][minlex[i]]){
                    a[1][minlex[i]]--;
                    desk[minlex[i]]++;
                    return 0;
                }
            }
            return 0;
        }
    }else if(h==2){
        if(a[2][r%13==0?13:r%13]>0){
            num=a[2][r%13==0?13:r%13];
            desk[r%13==0?13:r%13]+=a[2][r%13==0?13:r%13];
            a[2][r%13==0?13:r%13]=0;
            return 1;
        }
        else{
            num=1;
            for(int i=0;i<13;i++)
            {
                if(a[2][minlex[i]])
                {
                    a[2][minlex[i]]--;
                    desk[minlex[i]]++;
                    return 0;
                }
            }
            return 0;
        }
    }else if(h==3){
        if(a[3][r%13==0?13:r%13])
        {
            num=a[3][r%13==0?13:r%13];
            desk[r%13==0?13:r%13]+=a[3][r%13==0?13:r%13];
            a[3][r%13==0?13:r%13]=0;
            return 1;
        }else{
            int flag=0,mi=60;
            for(int i=0;i<13;i++){
                if(a[3][minlex[i]]==0) continue;
                if(a[3][minlex[i]]<mi){
                    mi=a[3][minlex[i]];flag=i;
                }
            }
            for(int i=0;i<13;i++){
                if(a[3][minlex[i]]==mi) {flag=i;break;}

            }
            num=mi;
            desk[minlex[flag]]+=a[3][minlex[flag]];
            a[3][minlex[flag]]=0;
            return 0;
        }
    }else{
        if(a[4][r%13==0?13:r%13]>=3){
            num=a[4][r%13==0?13:r%13];
            desk[r%13==0?13:r%13]+=a[4][r%13==0?13:r%13];
            a[4][r%13==0?13:r%13]=0;
            return 1;
        }else{
            num=a[4][r%13==0?13:r%13];
            desk[r%13==0?13:r%13]+=a[4][r%13==0?13:r%13];
            a[4][r%13==0?13:r%13]=0;
            for(int i=0;i<13;i++)
            {
                if(a[4][minlex[i]])
                {
                    a[4][minlex[i]]--;
                    desk[minlex[i]]++;
                    num++;
                    return 0;
                }
            }
            return 1;
        }
    }
}
int chall(int c,int hold,int r,int num){
    if(c==1){
        if((r)%4+1==c&&a[c][(r%13==0)?1:r%13+1]==0) return 1;
        if(a[c][r%13==0?13:r%13]+num>4) return 1;
    }else if(c==2){
        if((r)%4+1==c&&a[c][r%13==0?1:r%13+1]==0) return 1;
    }else if(c==3){
        if(a[c][r%13==0?13:r%13]==4) return 1;
    }else{
        int sum=0;
        for(int i=1;i<=13;i++){
            sum+=a[hold][i];
        }
        if(sum==0) return 1;
    }
    return 0;
}
int main()
{
    char sa[15][3];
    while(~scanf("%s",sa[0])){
        memset(a,0,sizeof(a));
        memset(desk,0,sizeof(desk));   
        if(sa[0][0]=='1') a[1][10]++;

        else if(sa[0][0]>='2'&&sa[0][0]<='9')
            a[1][sa[0][0]-'0']++;
        else{
            if(sa[0][0]=='A') a[1][1]++;
            else if(sa[0][0]=='J')  a[1][11]++;
            else if(sa[0][0]=='Q')  a[1][12]++;
            else if(sa[0][0]=='K')  a[1][13]++;
        }
        for(int j=1;j<=4;j++){
            int i;
            if(j==1) i=1;
            else i=0;
            for(;i<13;i++){
                scanf("%s",sa[i]);
                if(sa[i][0]=='1') a[j][10]++;

                else if(sa[i][0]>='2'&&sa[i][0]<='9')
                    a[j][sa[i][0]-'0']++;
                else{
                    if(sa[i][0]=='A') a[j][1]++;
                    else if(sa[i][0]=='J')  a[j][11]++;
                    else if(sa[i][0]=='Q')  a[j][12]++;
                    else if(sa[i][0]=='K')  a[j][13]++;
                }
            }
        }
        int round=1,flag;
        while(1){
            int hold=(round%4==0?4:round%4),num=0;

            int y=statement(hold,round,num);
            int x=0;
            for(int j=((hold+1)%4==0?4:(hold+1)%4);j!=hold&&x==0;j=((j+1)%4==0?4:(j+1)%4)){
                x=chall(j,hold,round,num);//x为是否挑战
                if(x==0) continue;
                if(y==1){
                    for(int i=1;i<=13;i++){
                        a[j][i]+=desk[i];
                        desk[i]=0;
                    }
                }else{
                    for(int i=1;i<=13;i++){
                        a[hold][i]+=desk[i];
                        desk[i]=0;
                    }
                }
                break;
            }
            flag=hold;
            int sum=0;
            for(int xx=1;xx<=4;xx++){
                sum=0;
                for(int i=1;i<=13;i++){
                    sum+=a[xx][i];
                }
                if(sum==0) {flag=xx;break;}
            }
            if(sum==0) break;
            round++;
        }
        for(int i=1;i<=4;i++){
            if(flag==i){
                printf("WINNER\n");continue;
            }
            int nn=0;
            for(int j=1;j<=13;j++){
                while(a[i][j]){
                    if(nn) printf(" ");
                    printf("%s",ma[j-1]);
                    a[i][j]--;
                    nn++;
                }
            }
            puts("");
        }
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值