[PKUSC2018]主斗地(搜索+贪心)

首先如果对子和三张牌出现在解中,那么全拆成单张显然没有问题,顺子同理。于是真正有用的牌型就只有单牌、三带一、三带二、四带二了。

暴搜jry手中的牌,然后先搜出双方的大牌型(即三张、四张牌的个数),再枚举三张牌带了几个对子,剩下的三张牌和四张牌带的都是单牌。这些被带的对子和单牌是没有大小限制的,所以对于jry手中的牌,应尽量带掉大牌,网友应尽量带掉小牌,这样才能尽量存在解。

最后剩的都是单牌了,扫一遍判断是否合法即可,总的来说没有坑点。

 1 #include<cstdio>
 2 #include<algorithm>
 3 #define rep(i,l,r) for (int i=(l); i<=(r); i++)
 4 using namespace std;
 5 
 6 const int N=20;
 7 int ans,g[300],a[N],b[N],c[N],d[N],e[N];
 8 char s[N];
 9 
10 int F(char c){ return (c>='4' && c<='9') ? c-'4' : g[(int)c]; }
11 
12 bool work(int o,int p){
13     rep(i,0,o){
14         int x=o+p-i,y=i;
15         rep(j,0,13) d[j]=c[j];
16         for (int j=13; ~j; j--){
17             while (y && d[j]>=2) d[j]-=2,y--;
18             while (x && d[j]) d[j]--,x--;
19         }
20         if (x|y) continue;
21         rep(j,0,13) e[j]=a[j];
22         x=o+p-i,y=i;
23         rep(j,0,13){
24             while (y && e[j]>=2) e[j]-=2,y--;
25             while (x && e[j]) e[j]--,x--;
26         }
27         if (x|y) continue;
28         x=0; bool flag=0;
29         rep(j,0,13){
30             if (e[j]>x){ flag=1; break; }
31             x+=d[j]-e[j];
32         }
33         if (!flag) return 1;
34     }
35     return 0;
36 }
37 
38 bool solve(int x,int o,int p,int q,int r){
39     if (x==14) return !q && !r && work(o,p);
40     bool f;
41     if (c[x]>=4){
42         c[x]-=4; f=solve(x+1,o,p+2,q,r+1); c[x]+=4;
43         if (f) return 1;
44     }
45     if (c[x]>=3){
46         c[x]-=3; f=solve(x+1,o+1,p,q+1,r); c[x]+=3;
47         if (f) return 1;
48     }
49     if (a[x]>=4 && r){
50         a[x]-=4; f=solve(x+1,o,p,q,r-1); a[x]+=4;
51         if (f) return 1;
52     }
53     if (a[x]>=3 && q){
54         a[x]-=3; f=solve(x+1,o,p,q-1,r); a[x]+=3;
55         if (f) return 1;
56     }
57     return solve(x+1,o,p,q,r);
58 }
59 
60 void dfs(int x,int s){
61     if (x==14){ if (!s && solve(0,0,0,0,0)) ans++; return; }
62     rep(i,0,min(s,b[x])) c[x]=i,dfs(x+1,s-i);
63 }
64 
65 int main(){
66     g['T']=6,g['J']=7,g['Q']=8,g['K']=9,g['A']=10,g['2']=11,g['w']=12,g['W']=13;
67     scanf("%s",s);
68     rep(i,0,11) b[i]=4; b[12]=b[13]=1;
69     rep(i,0,16) a[F(s[i])]++,b[F(s[i])]--;
70     dfs(0,17); printf("%d\n",ans);
71     return 0;
72 }

 

posted @ 2019-05-17 17:26  HocRiser  阅读(419)  评论(0编辑  收藏  举报