luogu2668 斗地主

81 篇文章 0 订阅
49 篇文章 0 订阅

http://www.elijahqi.win/archives/1376
题目描述

牛牛最近迷上了一种叫斗地主的扑克游戏。斗地主是一种使用黑桃、红心、梅花、方片的A到K加上大小王的共54张牌来进行的扑克牌游戏。在斗地主中,牌的大小关系根据牌的数码表示如下:3<4<5<6<7<8<9<10

#include<cstdio>
#include<cstring>
#include<algorithm>
#define inf 0x7f7f7f7f
#define N 20
using namespace std;
inline char gc(){
    static char now[1<<16],*S,*T;
    if (T==S){T=(S=now)+fread(now,1,1<<16,stdin);if (T==S) return EOF;}
    return *S++;
}
inline int read(){
    int x=0;char ch=gc();
    while (ch<'0'||ch>'9') ch=gc();
    while (ch<='9'&&ch>='0'){x=x*10+ch-'0';ch=gc();}
    return x;
}
int a[N],ans;
inline void calc(int step){
    int tmp[5];int ans1=step;memset(tmp,0,sizeof(tmp));
    for (int i=3;i<=16;++i) tmp[a[i]]++;int tt=0;
    if (tmp[2]>=tmp[4]*2) ans1+=tmp[4],tt=tmp[4],tmp[4]=0,tmp[2]-=tt*2;else ans1+=tmp[2]>>1,tmp[4]-=tmp[2]>>1,tmp[2]-=tmp[2]>>1<<1;
    if (tmp[1]>=tmp[4]*2) ans1+=tmp[4],tt=tmp[4],tmp[4]=0,tmp[1]-=tt*2;else ans1+=tmp[1]>>1,tmp[4]-=tmp[1]>>1,tmp[1]-=tmp[1]>>1<<1;
    ans1+=min(tmp[4],tmp[2]); tt=tmp[4];tmp[4]-=min(tmp[4],tmp[2]);tmp[2]-=min(tt,tmp[2]);
    ans1+=min(tmp[4],tmp[1]);tt=tmp[4];tmp[4]-=min(tmp[4],tmp[1]);tmp[1]-=min(tt,tmp[1]);
    for (int i=3;i>=3;--i){
        ans1+=min(tmp[i],tmp[2]);int tt=tmp[i];tmp[i]-=min(tmp[i],tmp[2]);tmp[2]-=min(tt,tmp[2]);
        ans1+=min(tmp[i],tmp[1]);tt=tmp[i];tmp[i]-=min(tmp[i],tmp[1]);tmp[1]-=min(tt,tmp[1]);
    } ans1+=tmp[4];ans1+=tmp[3];ans1+=tmp[2];ans1+=tmp[1]; 
    ans=min(ans,ans1);
} 
void dfs(int n,int step){
    bool flag=0;int q[20],top=0;
    //case单顺
    for (int i=3;i<=10;++i){
        for (int j=i;j<=14;++j){
            if (a[j]>0) {
                a[j]--;q[++top]=j;if (j-i+1>=5) dfs(n-(j-i+1),step+1),flag=1;
            }else break;
        }
        while (top) a[q[top--]]++;
    }top=0;
    //case 双顺
    for (int i=3;i<=12;++i){
        for (int j=i;j<=14;++j){
            if (a[j]>1) {
                a[j]-=2;q[++top]=j;if (j-i+1>=3) dfs(n-(j-i+1),step+1),flag=1;
            }else break;
        }
        while (top) a[q[top--]]+=2;
    }top=0;
    //case 三顺 
    for (int i=3;i<=12;++i){
        for (int j=i;j<=14;++j){
            if (a[j]>2) {
                a[j]-=3;q[++top]=j;if (j-i+1>=2) dfs(n-(j-i+1),step+1),flag=1;
            }else break;
        }
        while (top) a[q[top--]]+=3;
    }top=0;
    calc(step);
}
int n,T;
int main(){
//    freopen("landlords.in","r",stdin);
    T=read();n=read();
    while (T--){
        memset(a,0,sizeof(a));
        for (int i=1;i<=n;++i){
            int x=read(),xx=read();if (!x) a[16]++;
            if (x==1) a[14]++;if (x==2) a[15]++;if (x&&x!=1&&x!=2) a[x]++;
        }ans=inf;
        dfs(n,0);printf("%d\n",ans);
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值