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

ACM/ICPC 2018亞洲區預選賽北京賽站網路賽 C - Cheat

棋牌室成員+1

#include<bits/stdc++.h>
using namespace std;
#define For(i,a,b) for (int i=a;i<=b;i++)

map<string,int> own[4];
map<string,string> nxt;
string tw[13]={"10","2","3","4","5","6","7","8","9","A","J","K","Q"},ord[13]={"A","2","3","4","5","6","7","8","9","10","J","Q","K"};
vector<string> table;

inline string in()
{
    static char c[3];
    if (scanf("%s",c)==-1) exit(0);
    return (string)c;
}

inline void draw(int k,string s){own[k][s]++;}

inline int show(int k,string s)
{
    int rt=table.size();
    if (k==0)
    {
        if (own[k][s]) own[k][s]--,table.push_back(s);
        else For(i,0,12) if (own[k][tw[i]]) {own[k][tw[i]]--,table.push_back(tw[i]);break;}
    }
    if (k==1)
    {
        if (own[k][s]) for (;own[k][s];own[k][s]--) table.push_back(s);
        else For(i,0,12) if (own[k][tw[i]]) {own[k][tw[i]]--,table.push_back(tw[i]);break;}
    }
    if (k==2)
    {
        if (own[k][s]) for (;own[k][s];own[k][s]--) table.push_back(s);
        else
        {
            int tot=5;
            string op;
            For(i,0,12) if (own[k][tw[i]] && own[k][tw[i]]<tot) tot=own[k][tw[i]],op=tw[i];
            for (;own[k][op];own[k][op]--) table.push_back(op);
        }
    }
    if (k==3)
    {
        if (own[k][s]>2) for (;own[k][s];own[k][s]--) table.push_back(s);
        else
        {
            for (;own[k][s];own[k][s]--) table.push_back(s);
            For(i,0,12) if (own[k][tw[i]]) {own[k][tw[i]]--,table.push_back(tw[i]);break;}
        }
    }
    return table.size()-rt;
}

inline bool judge(int k)
{
    For(i,0,12) if (own[k][tw[i]]) return 0;
    return 1;
}

inline bool challenge(int ori,int k,string s,int num)
{
    if (k==0)
    {
        if (ori==3 && !own[k][nxt[s]]) return 1;
        if (num+own[k][s]>4) return 1;
        return 0;
    }
    if (k==1) return ori==0 && !own[k][nxt[s]];
    if (k==2) return own[k][s]==4;
    if (k==3) return judge(ori);
}

inline void showhand()
{
    For(i,0,3)
    {
        bool tot=0;
        For(j,0,12) for (;own[i][ord[j]];own[i][ord[j]]--) tot=1,cout<<ord[j]<<' ';
        if (!tot) cout<<"WINNER";
        cout<<'\n';
    }
}

inline void reveal(int ori,int k,string s,int num)
{
    For(i,1,num) if (table[table.size()-i]!=s)
    {
        for (auto s:table) draw(ori,s);
        return;
    }
    for (auto s:table) draw(k,s);
}

void round(int k,string s)
{
    int num=show(k,s);
    For(i,1,3) if (challenge(k,k+i&3,s,num)) {reveal(k,k+i&3,s,num);table.clear();break;}
    if (judge(k)) {showhand();return;}
    round(k+1&3,nxt[s]);
}

inline void solve()
{
    For(i,0,3) own[i].clear();
    For(j,0,3) For(i,0,12) draw(j,in());
    table.clear();
    round(0,"A");
}

inline void prepare()
{
    nxt["A"]="2";
    nxt["2"]="3";
    nxt["3"]="4";
    nxt["4"]="5";
    nxt["5"]="6";
    nxt["6"]="7";
    nxt["7"]="8";
    nxt["8"]="9";
    nxt["9"]="10";
    nxt["10"]="J";
    nxt["J"]="Q";
    nxt["Q"]="K";
    nxt["K"]="A";
}

int main()
{
    prepare();
    while(1) solve();
}