【hiho】2018ICPC北京赛区网络赛C Cheat(模拟)

题目链接

#1830 : Cheat

时间限制:1000ms

单点时限:1000ms

内存限制:256MB

描述

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 6 7 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

【题意】

4个人打牌,每个人每轮会分到13张牌,每个人都有自己的出牌方式,当达到每个人的质疑要求时每个人可以质疑他人,如果质疑成功那个人就压收回桌上所有的牌,否则就这个人收回桌上所有的牌,当某个人手中的牌都打完了则游戏结束,该人是赢家。

【解题思路】

反正是道炒鸡大的模拟题了,第一次写这么多代码。改了一天……感谢大佬。

把情况梳理清楚想清楚写就可以啦,没什么难度,但是感觉挺考验代码功底。

【代码】

#include<bits/stdc++.h>
using namespace std;
const int INF=0x3f3f3f3f;
map<string,int>m1;
string m2[]={"A","2","3","4","5","6","7","8","9","10","J","Q","K"};
int p[5][34],q[65],cur,flag,ans,r;
void init()
{
    m1["A"]=0;m1["2"]=1;m1["3"]=2;m1["4"]=3;m1["5"]=4;m1["6"]=5;
    m1["7"]=6;m1["8"]=7;m1["9"]=8;m1["10"]=9;m1["J"]=10;m1["Q"]=11;m1["K"]=12;
    memset(p,0,sizeof(p));
    memset(q,0,sizeof(q));
}
int minorder(int x)
{
    if(p[x][9]) return 9;
    for(int i=1;i<9;i++)
        if(p[x][i])
            return i;
    if(p[x][0])return 0;
    if(p[x][10])return 10;
    if(p[x][12])return 12;
    if(p[x][11])return 11;
    return -1;
}
int check(int x)
{
    for(int i=0;i<13;i++)
        if(p[x][i])
			return 0;
    return 1;
}
int roundholder(int x,int t)
{
    if(check(x))return 0;
    if(x==0)
    {
        if(p[x][t])
        {
            cur=t;
            p[x][t]--;
            q[t]++;
            r=1;
        }
        else
        {
            int y=minorder(x);
            cur=y;
            p[x][y]--;
            q[y]++;
            r=1;
        }
    }
    else if(x==1)
    {
        if(p[x][t])
        {
            cur=t;
            r=p[x][t];
            q[t]+=p[x][t];
            p[x][t]=0;
        }
        else
        {
            int y=minorder(x);
            cur=y;
            r=1;
            p[x][y]--;
            q[y]++;
        }
    }
    else if(x==2)
    {
        if(p[x][t])
        {
            cur=t;
            r=p[x][t];
            q[t]+=p[x][t];
            p[x][t]=0;
        }
        else
        {
            int mi = -1;
            if (p[x][9]) mi = 9;
            for(int i=1;i<9;++i)
		        if(p[x][i] && (mi == -1 || p[x][i] < p[x][mi]))
		   			 mi = i;
			if(p[x][0] && (mi == -1 || p[x][0] < p[x][mi])) mi = 0;
		   	if(p[x][10]&& (mi == -1 || p[x][10] < p[x][mi]))mi = 10;
		    if(p[x][12]&& (mi == -1 || p[x][12] < p[x][mi]))mi = 12;
		    if(p[x][11]&& (mi == -1 || p[x][11] < p[x][mi]))mi = 11;
		    
		    r=p[x][mi];
		    q[mi]+=r;
		    p[x][mi]=0;
		    cur=mi;
        }
    }
    else if (x==3)
    {
        if(p[x][t]>=3)
        {
            cur=t;
            r=p[x][t];
            q[t]+=r;
            p[x][t]=0;
        }
        else
        {
            if(p[x][t]>=1)
            {
                r=p[x][t];
                q[t]+=r;
                p[x][t]=0;
                int y=minorder(x);
                if(y==-1)cur=t;
                else
                {
                    cur=20;
                    r++;
                    p[x][y]--;
                    q[y]++;
                }
            }
            else
            {
                int y=minorder(x);
                cur=y;
                r=1;
                p[x][y]--;
                q[y]++;
            }
        }
    }
    return 1;
}
void away(int x)
{
    for(int i=0;i<13;i++)
        p[x][i]+=q[i];
    memset(q,0,sizeof(q));
}
void challenge(int x,int b,int t,int c)
{
    for(int ii=1;ii<4;ii++)
    {
        int i=(b+ii)%4;
        if(i==0 && i!=b)
        {
            if((!p[i][t] && b==3)|| p[i][c]+r>4)
            {
                if(cur!=c)
                    away(b);
                else 		
					away(i);
				return ;
            }
        }
        else if(i==1 && i!=b)
        {
            if(!p[i][t] && b==0)
            {
                if(cur!=c)
                    away(b);
                else 
					away(i);
                return ;
            }
        }
        else if(i==2 && i!=b)
        {
            if(p[i][c]==4)
            {
                if(cur!=c) 
					away(b);
                else 
					away(i);
                return ;
            }
        }
        else if(i==3 && i!=b)
        {
            if(check(b))
            {
                if(cur!=c)
                    away(b);
                else 
					away(i);
				return;
			}
        }
    }
    return ;
}
void print()
{
    for(int i=0;i<4;i++)
    {
        if(i==ans)printf("WINNER\n");
        else
        {
            int flag2=0;
            for(int j=0;j<13;j++)
            {
                if(p[i][j]>=1)
                {
                    for(int k=0;k<p[i][j];k++)
                    {
                        flag2?cout<<" "<<m2[j]:cout<<m2[j];
                        flag2=1;
                    }
                }
            }
            cout<<endl;
        }
    }
}
int main()
{
    string s;
    while(cin>>s)
    {
        init();
        int rh=0,t=0;
        flag=0;ans=INF,cur=0;
        p[0][m1[s]]++;
        for(int j=1;j<13;j++)
        {
            cin>>s;
            p[0][m1[s]]++;
        }
        for(int i=1;i<4;i++)
        {
            for(int j=0;j<13;j++)
            {
                cin>>s;
                p[i][m1[s]]++;
            }
        }
        while(1)
        {
            int z=roundholder(rh,t);
            if(!z)
            {
                ans=rh;
            	break;
            }
            else
            {
                int c=t,b=rh,z;
                t=(t+1)%13;
                rh=(rh+1)%4;
                challenge(rh,b,t,c);
                if (check(b)){
                	ans=b;
                	break;
				}
            }
        }
        print();
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_39826163/article/details/82838136