大模拟

工具人的自觉

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

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



计蒜客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;
}

原文地址:https://www.cnblogs.com/LiuRunky/p/Implementation.html

时间: 2024-11-06 15:35:42

大模拟的相关文章

AC日记——神奇的幻方 洛谷 P2615(大模拟)

题目描述 幻方是一种很神奇的N*N矩阵:它由数字1,2,3,……,N*N构成,且每行.每列及两条对角线上的数字之和都相同. 当N为奇数时,我们可以通过以下方法构建一个幻方: 首先将1写在第一行的中间. 之后,按如下方式从小到大依次填写每个数K(K=2,3,…,N*N): 1.若(K−1)在第一行但不在最后一列,则将K填在最后一行,(K−1)所在列的右一列: 2.若(K−1)在最后一列但不在第一行,则将K填在第一列,(K−1)所在行的上一行: 3.若(K−1)在第一行最后一列,则将K填在(K−1)

URAL 1715. Another Ball Killer (大模拟)

1715. Another Ball Killer Time limit: 2.0 second Memory limit: 64 MB Contestants often wonder what jury members do during a contest. Someone thinks that they spend all the contest fixing bugs in tests. Others say that the jury members watch the conte

POJ 1835 大模拟

宇航员 #include<iostream> #include<cstdio> #include<string> #include<cstring> #define maxn 10010 using namespace std; int a[7],temp[7]; char str[10]; void solve(int str2[],int str3[]) { if(strcmp(str,"forward")==0)//方向不变 { s

大模拟祭

考试的前一天晚上我还在和$letong$说,我以后晚上再颓就去打模拟,然后就考了个大模拟 我比较$sb$,各种情况全分开了,没怎么压行,打了$1000$行整,$30$多$k$,妈妈再也不怕我打不出来猪国杀了 1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 using namespace std; 5 int n,len,Std; 6 int b[5]; 7 char s[20],ss[20];

2017&quot;百度之星&quot;程序设计大赛 - 复赛1001&amp;&amp;HDU 6144 Arithmetic of Bomb【java大模拟】

Arithmetic of Bomb Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 129    Accepted Submission(s): 94 Problem Description 众所周知,度度熊非常喜欢数字. 它最近在学习小学算术,第一次发现这个世界上居然存在两位数,三位数……甚至N位数! 但是这回的算术题可并不简单,由于

UVALive 4222 /HDU 2961 Dance 大模拟

Dance Problem Description For a dance to be proper in the Altered Culture of Machinema, it must abide by the following rules: 1. A dip can only appear 1 or 2 steps after a jiggle, or before a twirl, as in:* ...jiggle dip...* ...jiggle stomp dip...* .

UVA 1596 Bug Hunt (大模拟 栈)

题意: 输入并模拟执行一段程序,输出第一个bug所在的行. 每行程序有两种可能: 数组定义: 格式为arr[size]. 例如a[10]或者b[5],可用下标分别是0-9和0-4.定义之后所有元素均为未初始化状态. 赋值语句: 格式为arr[index]=value. 或者arr[index] = arr[arr[index]]. 例如a[0]=3或者a[a[0]]=a[1]. 赋值语句和数组定义可能会出现两种bug: 下标index越界: 使用未初始化的变量(index和value都可 能出现

poj--2706--Connect(极限大模拟)

Connect Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 1148   Accepted: 375 Description Figure 1 Figure 2 Figure 3a Figure 3b Figure 4 Your task is to decide if a specified sequence of moves in the board game Twixt ends with a winning m

UVA 11210 Chinese Mahjong(中国麻将 , 大模拟)

解题思路: 关键在于如何判断十四张牌能否和牌,这里采用dfs来判断,详情看代码. #include <iostream> #include <cstring> #include <cstdlib> #include <cstdio> #include <algorithm> #include <vector> #include <queue> #include <set> #include <map>