1. 程式人生 > >ACM/ICPC 2018亞洲區預選賽北京賽站網路賽 C-cheat

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;
}