大模拟

工具人的自觉

尽量在对的前提下加快速度吧

也稍微总结下容易粗心的地方,慢慢补


计蒜客T42401 ($Poker\ Game$,$2019ICPC$南京)

一些调试中发现的错误:

1. 把第一次翻开的community card数量当成$2$(应该为$3$)→ 进而影响第$3,4$人在flop-betting时的正确性

2. 一开始没注意到只剩一人时就胜出 → 需要在每一轮都判断

3. 没注意到发牌可以不全发完

4. 看错第$1$人在flop-betting中call的条件

5. Three of a kind条件判错...

(WA1,通过$10/38$)

6. 初始时不是所有元素都在$last$中

7. 平局后的判断中,$cur$打成了$win$

8. 第$4$人在third-betting中的条件是$>$不是$\geq$

(WA2,通过$30/38$)

9. ideal的范围是$1$到$52$,而不是$2$到$14$

(WA3,通过$35/38$)

10. 在pre-flop中,可能因为有人因为unqualified导致vector访问越界

(AC)

这状态...EC根本不敢开模拟题啊...

稍微总结下,$10$个错误里面

看错条件$\times 3$,看漏条件$\times 2$,typo$\times 2$,边界条件$\times 1$,枚举范围$\times 1$,因特殊情况的越界$\times 1$

还是需要加油...

#include <cstdio>
#include <vector>
#include <cstring>
#include <cstdlib>
#include <algorithm>
using namespace std;

template <class T>
vector<T> operator +(vector<T> v1,vector<T> v2)
{
    for(int i=0;i<v2.size();i++)
        v1.push_back(v2[i]);
    return v1;
}

inline int val(int x)
{
    int res=(x-1)%13+1;
    return (res==1?14:res);
}
inline int suit(int x)
{
    return (x-1)/13;
}

inline int Highcard(vector<int> v)
{
    for(int i=0;i<v.size();i++)
        v[i]=val(v[i]);
    sort(v.begin(),v.end());
    return v.back();
}

inline int Pair(vector<int> v)
{
    int res=-1;
    for(int i=0;i<v.size();i++)
        v[i]=val(v[i]);
    sort(v.begin(),v.end());
    for(int i=1;i<v.size();i++)
        if(v[i]==v[i-1])
            res=v[i];
    return res;
}

inline int Three(vector<int> v)
{
    int res=-1;
    for(int i=0;i<v.size();i++)
        v[i]=val(v[i]);
    sort(v.begin(),v.end());
    for(int i=2;i<v.size();i++)
        if(v[i]==v[i-1] && v[i]==v[i-2])
            res=v[i];
    return res;
}

inline int Straight(vector<int> v)
{
    static int cnt[15];
    memset(cnt,0,sizeof(cnt));
    
    int res=-1;
    for(int i=0;i<v.size();i++)
        cnt[val(v[i])]++;
    cnt[1]=cnt[14];
    for(int i=1;i<=10;i++)
    {
        bool flag=true;
        for(int j=i;j<i+5;j++)
            if(!cnt[j])
                flag=false;
        if(flag)
            res=i+4;
    }
    return res;
}

inline int Flush(vector<int> v)
{
    static int cnt[5];
    memset(cnt,0,sizeof(cnt));
    
    int res=-1;
    for(int i=0;i<v.size();i++)
        cnt[suit(v[i])]++;
    for(int i=0;i<4;i++)
    {
        if(cnt[i]<5)
            continue;
        for(int j=0;j<v.size();j++)
            if(suit(v[j])==i)
                res=max(res,val(v[j]));
    }
    return res;
}

inline int rnk(vector<int> v)
{
    if(Flush(v)!=-1)
        return 5;
    if(Straight(v)!=-1)
        return 4;
    if(Three(v)!=-1)
        return 3;
    if(Pair(v)!=-1)
        return 2;
    return 1;
}

inline int high(vector<int> v)
{
    if(Flush(v)!=-1)
        return Flush(v);
    if(Straight(v)!=-1)
        return Straight(v);
    if(Three(v)!=-1)
        return Three(v);
    if(Pair(v)!=-1)
        return Pair(v);
    return Highcard(v);
}

inline int major(vector<int> v)
{
    static int cnt[15];
    memset(cnt,0,sizeof(cnt));
    
    for(int i=0;i<v.size();i++)
        v[i]=val(v[i]),cnt[v[i]]++;
    for(int i=0;i<v.size();i++)
        if(cnt[v[i]]>1)
            return v[i];
    return -1;
}

inline int valmax(vector<int> v)
{
    int res=-1;
    for(int i=0;i<v.size();i++)
        res=max(res,val(v[i]));
    return res;
}

inline int countmax(vector<int> v)
{
    static int cnt[5];
    memset(cnt,0,sizeof(cnt));
    
    int res=0;
    for(int i=0;i<v.size();i++)
        cnt[suit(v[i])]++;
    for(int i=0;i<4;i++)
        res=max(res,cnt[i]);
    return res;
}

inline int thirdhighest(vector<int> v)
{
    for(int i=0;i<v.size();i++)
        v[i]=val(v[i]);
    sort(v.begin(),v.end());
    return v[(int)v.size()-3];
}

int card[16];
vector<int> v[6],three,five;

int jackpot,pot[6];
bool in[6],fold[6];

vector<int> last,alive;

void print()
{
    for(int i=1;i<=5;i++)
        printf("%d",fold[i]);
    putchar('\n');
}

int main()
{
    for(int i=1;i<=5;i++)
        pot[i]=100;
    
    int T;
    scanf("%d",&T);
    while(T--)
    {
//        for(int i=1;i<=5;i++)
//            printf("%d ",pot[i]);
//        printf("\n\n");
        
        jackpot=0;
        for(int i=1;i<=5;i++)
        {
            v[i].clear();
            if(pot[i]>0)
                last.push_back(i);
        }
        three.clear(),five.clear();
        
        for(int i=1;i<=15;i++)
            scanf("%d",&card[i]);
        int id=1;
        for(int i=1;i<=5;i++)
            if(pot[i]>0)
            {
//                printf("person %d: (%d,%d) (%d,%d)\n",i,suit(card[id]),val(card[id]),
//                    suit(card[id+1]),val(card[id+1]));
                v[i].push_back(card[id]);
                v[i].push_back(card[id+1]);
                id+=2;
            }
        for(int i=id;i<id+3;i++)
            three.push_back(card[i]);
//        printf("community: ");
        for(int i=id;i<id+5;i++)
        {
//            printf("(%d,%d) ",suit(card[i]),val(card[i]));
            five.push_back(card[i]);
        }
//        putchar('\n');
        
        int person=0;
        memset(in,false,sizeof(in));
        memset(fold,false,sizeof(fold));
        
        for(int i=1;i<=5;i++)
            if(pot[i]==0)
                fold[i]=true;
        
        // Pre-flop
//        printf("pre-flop\n");
        
        if(!fold[1])
        if(pot[1]<15)
            fold[1]=true;
        else
            if(suit(v[1][0])==suit(v[1][1]))
                jackpot+=5,pot[1]-=5,person++;
            else
                fold[1]=true;
        
        if(!fold[2])
        if(pot[2]>=15)
            jackpot+=5,pot[2]-=5,person++;
        else
            if(val(v[2][0])==14 && val(v[2][1])==14)
                in[2]=true,jackpot+=pot[2],pot[2]=0,person++;
            else
                fold[2]=true;
        
        if(!fold[3])
        if(val(v[3][0])==14 || val(v[3][1])==14 || abs(val(v[3][1])-val(v[3][0]))<3)
            if(pot[3]>=15)
                jackpot+=5,pot[3]-=5,person++;
            else
                in[3]=true,jackpot+=pot[3],pot[3]=0,person++;
        else
            fold[3]=true;
        
        if(!fold[4])
        if(valmax(v[4])>11)
            if(pot[4]>=15)
                jackpot+=5,pot[4]-=5,person++;
            else
                in[4]=true,jackpot+=pot[4],pot[4]=0,person++;
        else
            fold[4]=true;
        
        if(!fold[5])
        if(person==1)
            if(pot[5]>=15)
                jackpot+=5,pot[5]-=5;
            else
                in[5]=true,jackpot+=pot[5],pot[5]=0;
        else
            fold[5]=true;
        
//        print();
        
        alive.clear();
        for(int i=1;i<=5;i++)
            if(!fold[i])
                alive.push_back(i);
        if((int)alive.size()==0)
        {
            pot[last.back()]+=jackpot;
            continue;
        }
        else
            last=alive;
        
        // Flop
//        printf("flop\n");
        
        if(!fold[1] && !in[1])
            jackpot+=5,pot[1]-=5;
        
        if(!fold[2] && !in[2])
            if(rnk(v[2]+three)>=2)
                jackpot+=5,pot[2]-=5;
            else
            {
                bool flag=false;
                vector<int> add;
                for(int i=1;i<=52;i++)
                {
                    add.clear(),add.push_back(i);
                    if(rnk(v[2]+three+add)>=4)
                        flag=true;
                }
                if(flag)
                    jackpot+=5,pot[2]-=5;
                else
                    fold[2]=true;
            }
        
        if(!fold[3] && !in[3])
            if(major(three)!=-1 && major(three)!=val(v[3][0]) &&
                major(three)!=val(v[3][1]))
                fold[3]=true;
            else
                jackpot+=5,pot[3]-=5;
        
        if(!fold[4] && !in[4])
            if(valmax(v[4])>=valmax(three))
                jackpot+=5,pot[4]-=5;
            else
                fold[4]=true;
        
        if(!fold[5] && !in[5])
            jackpot+=5,pot[5]-=5;
        
//        print();
        
        alive.clear();
        for(int i=1;i<=5;i++)
            if(!fold[i])
                alive.push_back(i);
        if((int)alive.size()==0)
        {
            pot[last.back()]+=jackpot;
            continue;
        }
        else
            last=alive;
        
        // Third
//        printf("third\n");
        
        if(!fold[1] && !in[1])
            if(rnk(v[1]+five)>=2)
                jackpot+=5,pot[1]-=5;
            else
                fold[1]=true;
        
        if(!fold[2] && !in[2])
            if(countmax(five)>=4)
                fold[2]=true;
            else
                jackpot+=5,pot[2]-=5;
        
        if(!fold[3] && !in[3])
            jackpot+=5,pot[3]-=5;
        
        if(!fold[4] && !in[4])
            if(rnk(v[4]+five)>=3 || 
                (rnk(v[4]+five)==2 && Pair(v[4]+five)>thirdhighest(five)))
                jackpot+=5,pot[4]-=5;
            else
                fold[4]=true;
        
        if(!fold[5] && !in[5])
            jackpot+=5,pot[5]-=5;
        
//        print();
        
        alive.clear();
        for(int i=1;i<=5;i++)
            if(!fold[i])
                alive.push_back(i);
        
        if((int)alive.size()==0)
        {
            pot[last.back()]+=jackpot;
            continue;
        }
        
        int win=alive[0];
        for(int i=1;i<alive.size();i++)
        {
            int cur=alive[i];
            if(rnk(v[win]+five)<rnk(v[cur]+five) ||
                (rnk(v[win]+five)==rnk(v[cur]+five) && high(v[win]+five)<=high(v[cur]+five)))
                win=cur;
        }
        pot[win]+=jackpot;
    }
    
    for(int i=1;i<=5;i++)
        printf("%d\n",pot[i]);
    return 0;
}
View Code

猜你喜欢

转载自www.cnblogs.com/LiuRunky/p/Implementation.html