【luogu2668斗地主】模拟
题目描述:


输入格式:

输出格式:

输入样例:
1:
1 8 7 4 8 4 9 1 10 4 11 1 5 1 1 4 1 1
2:
1 17 12 3 4 3 2 3 5 4 10 2 3 3 12 2 0 1 1 3 10 1 6 2 12 1 11 3 5 2 12 4 2 2 7 2
输出样例:
1:
3
2:
4
数据范围:

思想:模拟
代码:
#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cstring>
#define MAXN 100000
using namespace std;
int card[17],cnt,ans=5211314,T,n;
int read()
{
int x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
void dfs(int pos)
{
if(pos>=ans)return;////////求有多少个单顺子
int k=0;
for(int i=3;i<=14;i++)
{
if(!card[i])k=0;
else{
k++;
if(k>=5){
for(int j=i;j>=j-k+1;j--)
card[j]--;
dfs(pos+1);
for(int j=i;j>=j-k+1;j--)
card[j]++;
}
}
}
k=0;
for(int i=3;i<=14;i++)////求有多少个双顺子
{
if(card[i]<2)k=0;
else{
k++;
if(k>=3)
{
for(int j=i;j>=i-k+1;j--)
card[j]-=2;
dfs(pos+1);
for(int j=i;j>=j-k+1;j--)
card[j]+=2;
}
}
}
for(int i=2;i<=14;i++)////三张牌的情况
{
if(card[i]<=3)
{
if(card[i]<3)continue;
card[i]-=3;
for(int j=2;j<=15;j++)////三张牌带一张牌
{
if(j==i||card[j]<1)continue;
card[j]--;
dfs(pos+1);
card[j]++;
}
for(int j=2;j<=15;j++)
{
if(j==i||card[j]<2)continue;////三张牌带两张牌
card[j]-=2;
dfs(pos+1);
card[j]+=2;
}
card[i]+=3;
}
else
{
card[i]-=3;
for(int j=2;j<=15;j++)
{
if(j==i||card[j]<1)continue;
card[j]--;
dfs(pos+1);
card[j]++;
}
for(int j=2;j<=15;j++)
{
if(j==i||card[j]<2)continue;
card[i]-=2;
dfs(pos+1);
card[j]+=2;
}
card[i] += 3;//三张带别的
card[i] -= 4;//四张带两个单张
for(int j = 2; j <= 15; ++j){
if(j == i || card[j] < 1) continue;
card[j]--;
for(int k = 2; k <= 15; ++k){
if(k == j || card[k] < 1) continue;
card[k]--;
dfs(pos+1);
card[k]++;
}
card[j]++;
}
for(int j = 2; i <= 14; ++j){////四张带两个对
if(j == i || card[j] < 2) continue;
card[j] -= 2;
for(int k = 2; k <= 14; ++k){
if(j == k || card[k] < 2) continue;
card[k] -= 2;
dfs(pos+1);
card[k] += 2;
}
card[j] += 2;
}
card[i] += 4;
}
}
for(int i=2;i<=15;++i)////考虑剩下的牌,每次都能一次出尽每种的所有牌
if(card[i])pos++;
ans=min(ans,pos);
}
int main()
{
T=read();n=read();
while(T--)
{
ans=2147483647;
memset(card,0,sizeof(card));
int ai,bi;
for(int i=1;i<=n;i++)
{
ai=read();bi=read();
if(ai==1)card[14]++;
else if(ai==0)card[15]++;
else card[ai]++;
}
dfs(0);
printf("%d\n",ans);
}
return 0;
}

浙公网安备 33010602011771号