首页 > 其他分享 >斗地主

斗地主

时间:2023-10-07 20:24:20浏览次数:31  
标签:cnt 斗地主 int -- include 顺子 define

P2668 [NOIP2015 提高组] 斗地主

我们发现,除了顺子以外,其他的出牌方式和大小无关,我们先爆搜所有的顺子,搜索完之后剩下的牌我们考虑不用顺子,用其他牌型。

此时我们关心的只有单牌、对子、三个、炸弹四种,每种分别最多 \(23,11,7,5\) 个,状态很少,记忆化即可。

注意加强版需要额外一维表示是否有双王,双王可以当对子出,但是不能四带二;但是可以三带一,我们可以特殊判断,如果只剩一张王,把它划入普通单牌的行列。

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
#define Ed for(int i=h[x];~i;i=ne[i])
#define Ls(i,l,r) for(int i=l;i<r;++i)
#define Rs(i,l,r) for(int i=l;i>r;--i)
#define Le(i,l,r) for(int i=l;i<=r;++i)
#define Re(i,l,r) for(int i=l;i>=r;--i)
#define L(i,l) for(int i=0;i<l;++i)
#define E(i,l) for(int i=1;i<=l;++i)
#define W(t) while(t--)
#define Wh while

const int N=1,INF=100,len[]={0,5,3,2};
int T,n,f[24][12][8][6];
int calc(int s[]){
    E(i, 4)
        if(s[i]<0)return INF;
    int sum=0;
    E(i, 4)sum+=s[i];
    int &v=f[s[1]][s[2]][s[3]][s[4]];
    if(~v)return v;
    if(!sum)return v=0;
    v=INF;
    E(i, 4)
        Le(k, i, 4){
            --s[k],++s[k-i];
            v=min(v,calc(s)+1);
            if(i==3){
                Le(x, 1, 2)
                    Le(y, x, 4){
                        --s[y],++s[y-x];
                        v=min(v,calc(s)+1);
                        ++s[y],--s[y-x];
                    }
            }
            if(i==4){
                Le(x, 1, 2)
                    Le(y, x, 4)
                        Le(z, x, 4){
                            --s[y],++s[y-x];
                            --s[z],++s[z-x];
                            v=min(v,calc(s)+1);
                            ++s[y],--s[y-x];
                            ++s[z],--s[z-x];
                        }
            }
            ++s[k],--s[k-i];
        }
    return v;
}
void add(int a[],int l,int r,int k){
    Le(i, l, r)
        a[i]+=k;
}
bool chk(int a[],int l,int r,int k){
    Le(i, l, r)
        if(a[i]<k)return false;
    return true;
}
int dfs(int cnt[]){
    L(i, 14)
        if(cnt[i]<0)return INF;
    int tmp[5]={};
    L(i, 14)
        ++tmp[cnt[i]];
    int ans=calc(tmp);
    E(i, 3)
        Le(l, 2, 13)
            Le(r, l+1, 13){
                if(r-l+1<len[i]||!chk(cnt,l,r,i))continue;
                add(cnt,l,r,-i);
                ans=min(ans,dfs(cnt)+1);
                add(cnt,l,r,i);
            }
    return ans;
}
int main(){
    #ifndef ONLINE_JUDGE
    freopen("1.in","r",stdin);
    #endif
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    cin>>T>>n;
    memset(f,-1,sizeof f);
    W(T){
        int cnt[14]{};
        E(i, n){
            int a,b;
            cin>>a>>b;
            if(a==1)a=13;
            else if(a)a--;
            ++cnt[a];
        }
        cout<<dfs(cnt)<<'\n';
    }
    return 0;
}

加强版

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
#define Ed for(int i=h[x];~i;i=ne[i])
#define Ls(i,l,r) for(int i=l;i<r;++i)
#define Rs(i,l,r) for(int i=l;i>r;--i)
#define Le(i,l,r) for(int i=l;i<=r;++i)
#define Re(i,l,r) for(int i=l;i>=r;--i)
#define L(i,l) for(int i=0;i<l;++i)
#define E(i,l) for(int i=1;i<=l;++i)
#define W(t) while(t--)
#define Wh while

const int N=1,INF=100,len[]={0,5,3,2};
int T,n,f[24][12][8][6][2];
bool two_king;
int calc(int s[],bool two){
    E(i, 4)
        if(s[i]<0)return INF;
    int sum=0;
    E(i, 4)sum+=s[i];
    int &v=f[s[1]][s[2]][s[3]][s[4]][two];
    if(~v)return v;
    if(!sum&&!two)return v=0;
    v=INF;
    if(two)v=min(v,calc(s,0)+1);
    E(i, 4)
        Le(k, i, 4){
            --s[k],++s[k-i];
            v=min(v,calc(s,two)+1);
            if(i==3){
                Le(x, 1, 2)
                    Le(y, x, 4){
                        --s[y],++s[y-x];
                        v=min(v,calc(s,two)+1);
                        ++s[y],--s[y-x];
                    }
                ++s[1];
                v=min(v,calc(s,two-1)+1);
                --s[1];
            }
            if(i==4){
                Le(x, 1, 2)
                    Le(y, x, 4)
                        Le(z, x, 4){
                            --s[y],++s[y-x];
                            --s[z],++s[z-x];
                            v=min(v,calc(s,two)+1);
                            ++s[y],--s[y-x];
                            ++s[z],--s[z-x];
                        }
            }
            ++s[k],--s[k-i];
        }
    return v;
}
void add(int a[],int l,int r,int k){
    Le(i, l, r)
        a[i]+=k;
}
bool chk(int a[],int l,int r,int k){
    Le(i, l, r)
        if(a[i]<k)return false;
    return true;
}
int dfs(int cnt[]){
    int tmp[5]={},two=0;
    L(i, 14)
        if(!i)two=cnt[i]==2;
        else ++tmp[cnt[i]];
    if(!two)++tmp[cnt[0]];
    int ans=calc(tmp,two);
    E(i, 3)
        Le(l, 2, 13)
            Le(r, l+1, 13){
                if(r-l+1<len[i]||!chk(cnt,l,r,i))continue;
                add(cnt,l,r,-i);
                ans=min(ans,dfs(cnt)+1);
                add(cnt,l,r,i);
            }
    return ans;
}
int main(){
    #ifndef ONLINE_JUDGE
    freopen("1.in","r",stdin);
    #endif
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    cin>>T>>n;
    memset(f,-1,sizeof f);
    W(T){
        int cnt[14]{};
        E(i, n){
            int a,b;
            cin>>a>>b;
            if(a==1)a=13;
            else if(a)a--;
            ++cnt[a];
        }
        two_king=cnt[0]==2;
        cout<<dfs(cnt)<<'\n';
    }
    return 0;
}

标签:cnt,斗地主,int,--,include,顺子,define
From: https://www.cnblogs.com/wscqwq/p/17747366.html

相关文章

  • 集合:综合案例:斗地主业务分析
     packagecom.GameDemo;publicclassGameDemo{publicstaticvoidmain(String[]args){Rooms=newRoom();//启动游戏s.start();}}packagecom.GameDemo;publicclassCard{privateStringnumber;privateStri......
  • 华为OD机试 斗地主 2
    本期题目:斗地主2......
  • 模仿斗地主发牌
    packagecom.st.text;importjava.util.ArrayList;importjava.util.Collections;/**1.一副扑克牌有54张牌,扑克的图形有梅花,方片,黑桃,红心数字有A1,2,3.......JQK......
  • 电脑浏览器知识普及:别再安装那么多浏览器啦,又不是斗地主
    2023年了,不会真的有很多人不了解浏览器,傻傻地在电脑上安装3、4个浏览器吧?不管你之前对浏览器的知识怎样,也不管你在电脑上安装多少个浏览器,现在以下面普及的电脑浏览器知识......
  • 第二十三章《斗地主游戏》第2节:系统功能实现
    地主游戏的功能模块非常多,本小节将介绍各功能模块的实现思路及基本源代码。23.2.1游戏服务器的启动在server包下有一个Main类,这个类中包含main()方法,main()方法中包含启动游......
  • 第二十三章《斗地主游戏》第3节:项目完整代码
    对于初学者来说,斗地主游戏是一个比较复杂的项目,它涉及的类很多,以下是这个项目所有类的源代码,源码中有两个Main.java文件,它们虽然文件名称相同,但位于不同的包下,读者在复制粘......
  • 第二十三章《斗地主游戏》第1节:斗地主项目简介
     斗地主游戏是一款3人参与的棋牌游戏,3方用一副牌(54张)展开游戏,其中一方为地主,其余两家为另一方,双方对战,先出完牌的一方获胜。用计算机程序实现的斗地主程序需要3个客户端,每......
  • 集合之斗地主案例
    1packagecom.Lucky.AppUnit;23/**4*开启App入口5*/6publicclassApp{7publicstaticvoidmain(String[]args){8//newstart......
  • Java斗地主洗牌分牌
     packagecn.edu.lcudcc.collection_test;publicclassCard{privateStringsize;privateStringcolor;privateintindex;//真正的大小pu......
  • 前期斗地主案例
    实体类packagecom.itheima.d3_collection_test;publicclassCard{privateStringnumber;//点数privateStringcolor;//花色privateintsize;......