假斗地主 - 搜索

题目大意:规则和斗地主一样,问为能否在不出超过1张单牌的情况下把牌出完,如果不能则问所有出牌方案中,第二小的单牌最大是多少。
题解:直接搜即可。

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define mp make_pair
#define fir first
#define sec second
using namespace std;
typedef pair<int,int> pii;typedef set<int>::iterator sit;const int m=17,xw=16,dw=17,A=14,_2=15,N=30;int cnt[N],ans,n,t;char str[N];pii s[N];
inline int min2_one() { int k=2;rep(i,3,m) { if(k<=cnt[i]) return i;k-=cnt[i]; }return 0; } inline int c(int x,int y) { return cnt[x]>=y; }
inline int g(int x,int y) { return cnt[x]-=y,s[++t]=mp(x,y),n-=y,0; } inline int back() { return cnt[s[t].fir]+=s[t].sec,n+=s[t].sec,t--; }
int dfs()
{
	if(ans==-1||n<=1) return ans=-1;ans=max(ans,min2_one());
	rep(i,3,m) if(c(i,4)) { g(i,4);rep(j,3,m) if(c(j,1)) { g(j,1);rep(k,3,m) if(c(k,1)) g(k,1),dfs(),back();back(); } back(); }
	rep(i,3,m) if(c(i,3)) { g(i,3);rep(j,3,m) if(c(j,1)) g(j,1),dfs(),back();back(); }
	rep(i,3,m) if(c(i,3)) g(i,3),dfs(),back();rep(i,3,m) if(c(i,2)) g(i,2),dfs(),back();
	if(c(dw,1)&&c(xw,1)) g(dw,1),g(xw,1),dfs(),back(),back();
	rep(i,3,m) for(int j=A;j>=i+4;j--) { int ok=1;rep(k,i,j) ok&=c(k,1); if(ok) { rep(k,i,j) g(k,1);dfs();rep(k,i,j) back(); } }
	return 0;
}
int main()
{
	scanf("%d%s",&n,str+1);
	rep(i,1,n)
	{
		if(str[i]>='3'&&str[i]<='9') cnt[str[i]^'0']++;
		if(str[i]=='T') cnt[10]++;
		if(str[i]=='J') cnt[11]++;
		if(str[i]=='Q') cnt[12]++;
		if(str[i]=='K') cnt[13]++;
		if(str[i]=='A') cnt[A]++;
		if(str[i]=='2') cnt[_2]++;
		if(str[i]=='w') cnt[xw]++;
		if(str[i]=='W') cnt[dw]++;
	}
	dfs();
	if(ans==-1) return !printf("%d\n",ans);
	if(ans>=3&&ans<=9) return !printf("%d\n",ans);
	if(ans==10) return !printf("T\n");
	if(ans==11) return !printf("J\n");
	if(ans==12) return !printf("Q\n");
	if(ans==13) return !printf("K\n");
	if(ans==A) return !printf("A\n");
	if(ans==_2) return !printf("2\n");
	if(ans==xw) return !printf("w\n");
	if(ans==dw) return !printf("W\n");
	return 0;
}

猜你喜欢

转载自blog.csdn.net/Mys_C_K/article/details/83504005
今日推荐