【问题描述】
牛牛最近迷上了一种叫斗地主的扑克游戏。斗地主是一种使用黑桃、红心、梅花、方片的 A 到K 加上大小王的共 54 张牌来进行的扑克牌游戏。在斗地主中,牌的大小关系根据牌的数码表示如下:3<4<5<6<7<8<9<10<J<Q<K<A<2<小王<大王,而花色并不对牌的大小产生影响。每一局游戏中,一副手牌由n 张牌组成。游戏者每次可以根据规定的牌型进行出牌,首先打光自己的手牌一方取得游戏的胜利。
现在,牛牛只想知道,对于自己的若干组手牌,分别最少需要多少次出牌可以将它们打光。请你帮他解决这个问题。
需要注意的是,本题中游戏者每次可以出手的牌型与一般的斗地主相似而略有不同。具体规则如下:
【输入格式】
输入文件名为 landlords.in。
第一行包含用空格隔开的 2 个正整数?, ? ,表示手牌的组数以及每组手牌的张数。接下来? 组数据,每组数据? 行,每行一个非负整数对 ??, ??,表示一张牌,其中 ??表示牌的数码,?? 表示牌的花色,中间用空格隔开。特别的,我们用 1 来表示数码 A,11 表示数码 J,12 表示数码Q,13 表示数码 K;黑桃、红心、梅花、方片分别用 1-4 来表示;小王的表示方法为 0 1,大王的表示方法为 0 2。
【输出格式】
输出文件名为 landlords.out。
共 T 行,每行一个整数,表示打光第?组手牌的最少次数。
据说这道题只有赌神才能做出来……
欲做此题,先打好斗地主
emm....就是一个大模拟、大暴力
code
#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; const int INF=0x3f3f3f3f; int T,n,ans; int a[110],ton[110]; void dfs(int stp) { if(stp>=ans) return ; int k=0; for(int i=3;i<=14;++i) { //单顺子 3~A if(ton[i]) { k++; if(k>=5) { for(int j=i;j>i-k;--j) ton[j]--; dfs(stp+1); for(int j=i;j>i-k;--j) ton[j]++; } } else k=0; } k=0; for(int i=3;i<=14;++i) { //双顺子 3~A if(ton[i]>=2) { k++; if(k>=3) { for(int j=i;j>i-k;--j) ton[j]-=2; dfs(stp+1); for(int j=i;j>i-k;--j) ton[j]+=2; } } else k=0; } k=0; for(int i=3;i<=14;++i) { //三顺子 3~A if(ton[i]>=3) { k++; if(k>=2) { for(int j=i;j>i-k;--j) ton[j]-=3; dfs(stp+1); for(int j=i;j>i-k;--j) ton[j]+=3; } } else k=0; } //带牌 for(int i=2;i<=14;++i) //2~A { if(ton[i]>=3) { ton[i]-=3; for(int j=1;j<=14;++j) { //3 d 1 if(ton[j]<1) continue; ton[j]--; dfs(stp+1); ton[j]++; } for(int j=2;j<=14;++j) { //3 d 2 不能带王炸 if(ton[j]<2) continue; ton[j]-=2; dfs(stp+1); ton[j]+=2; } ton[i]+=3; } if(ton[i]==4) { ton[i]-=4; for(int j=1;j<=14;++j) //4 d 2 { if(ton[j]<1) continue; ton[j]--; for(int l=1;l<=14;++l) { if(ton[l]<1 || l==j) continue; //带双单不能重 ton[l]--; dfs(stp+1); ton[l]++; } ton[j]++; } for(int j=2;j<=14;++j) //不能带王炸 { if(ton[j]<2) continue; ton[j]-=2; for(int l=2;l<=14;++l) { if(ton[l]<2 || l==j) continue; //双对也不能重 ton[l]-=2; dfs(stp+1); ton[l]+=2; } ton[j]+=2; } ton[i]+=4; } } for(int i=1;i<=14;++i) if(ton[i]) stp++; ans=min(ans,stp); } int main() { scanf("%d%d",&T,&n); while(T--) { ans=INF; memset(ton,0,sizeof(ton)); for(int i=1;i<=n;++i) { int x,y; scanf("%d%d",&x,&y); if(x==1) a[i]=14; else if(x==0) a[i]=1; else a[i]=x; ton[a[i]]++; } sort(a+1,a+1+n); dfs(0); printf("%d\n",ans); } return 0; } /* 1 8 7 4 8 4 9 1 10 4 11 1 5 1 1 4 1 1 */