http://acm.hdu.edu.cn/showproblem.php?pid=4930
就是两个人玩斗地主,有8种牌型,单张,一对,三张,三带一,三带对,四带二,四炸,王炸。问先手能否一次出完牌或者出的第一手牌让对方无牌可出!!能则输出yes。
恶心模拟
8种组合: 1.单牌:一张牌
2.对子:两张相同的牌
3.三重奏(百度翻译出来的。。):三张相同的牌
4.三带一:三张相同的带一张牌(大小只考虑前面的牌,不考虑带的)
5.三带二:三张相同的带两张牌,带的两张牌可以一样,也可以不一样(大小只考虑前面的牌,不考虑带的)
6.四带二:四个相同的带两张牌,带的两张牌可以一样,也可以不一样(大小只考虑前面的牌,不考虑带的)
7.炸弹:四个相同的一起出,不带任何东西(能管除了核弹所有的)
8.核弹:大小王一起(能管所有的牌)
注意: 1.4张相同的牌带两张牌的话是可以被炸弹炸的;
2.不能四带一
3.特判先手一次出完的情况
#include <cstdio> #include <cstdlib> #include <cmath> #include <cstring> #include <string> #include <queue> #include <vector> #include <iostream> #include <algorithm> using namespace std; #define RD(x) scanf("%d",&x) #define RD2(x,y) scanf("%d%d",&x,&y) #define clr0(x) memset(x,0,sizeof(x)) typedef long long LL; int u[19], v[19], w[19]; int t,s,n,m; int id(char temp) { if (temp=='Y') return 17; if (temp=='X') return 16; if (temp=='2') return 15; if (temp=='A') return 14; if (temp=='K') return 13; if (temp=='Q') return 12; if (temp=='J') return 11; if (temp=='T') return 10; return temp-'0'; } bool check() { int i,j,k; if (v[16]>=1 && v[17]>=1) { return 1; } if (m==2) { if (w[16]>=1 && w[17]>=1) return 0; } if (m==4) { for (i=3; i<=15; ++i) if (w[i]>=4){ //炸弹 for (j=i+1; j<=15; ++j) if (v[j]>=4) return 1; return 0; } } for (j=3; j<=15; ++j) if (v[j]>=4) return 1; if (n<m) return 0; if (m==1) { for (i=3; i<=17; ++i) if (w[i]>=1){ for (j=i+1; j<=17; ++j) if (v[j]>=1) return 1; return 0; } } if (m==2) { for (i=3; i<=15; ++i) if (w[i]>=2) { for (j=i+1; j<=15; ++j) if (v[j]>=2) return 1; return 0; } } if (m==3) { for (i=3; i<=15; ++i) if (w[i]>=3) { for (j=i+1; j<=15; ++j) if (v[j]>=3) return 1; return 0; } } if (m==4) { for (i=3; i<=15; ++i) if (w[i]>=3){ //三带一 for (j=i+1; j<=15; ++j) if (v[j]>=3) return 1; return 0; } } if (m==5) { for (i=3; i<=15; ++i) if (w[i]>=3){ //三带对 for (j=i+1; j<=15; ++j) if (v[j]>=3) { break; } if (j>=16) return 0; for (k=3; k<=15; ++k) { if (k!=j && v[k]>=2) return 1; } return 0; } } return 0; } bool solve() { int i,j,k; if (u[16]>=1 && u[17]>=1) { return 1; } if (s==4 || s==6) { for (i=3; i<=15; ++i) if (u[i]>=4) return 1; } if (s==1) { return 1; } if (s==2) { for (i=3; i<=15; ++i) if (u[i]>=2) return 1; } if (s==3) { for (i=3; i<=15; ++i) if (u[i]>=3) return 1; } if (s==4) { for (i=3; i<=15; ++i) if (u[i]>=3) return 1; } if (s==5) { for (i=3; i<=15; ++i) if (u[i]>=3){ for (k=3; k<=15; ++k) if (k!=i && u[k]>=2) return 1; } } for (i=3; i<=17; ++i){ if (u[i]>=4) { clr0(w); w[i]=u[i]; m = u[i]; if (!check()) return 1; } else if (u[i]>=3) { for (j=3;j<=17;++j) if (j!=i && u[j]>=2){ clr0(w); w[i]=u[i]; w[j]=2; m = u[i] + 2; if (!check()) return 1; } clr0(w); w[i]=u[i]; m = u[i]; if (!check()) return 1; if (s>3){ for (j=3;j<=17;++j) if (j!=i) break; w[j]=1; m = u[i] + 1; if (!check()) return 1; } } else if (u[i]>=2){ clr0(w); w[i]=u[i]; m = u[i]; if (!check()) return 1; } else if (u[i]>=1){ clr0(w); w[i]=u[i]; m = u[i]; if (!check()) return 1; } } return 0; } int main() { char a[19], b[19]; int i; RD(t); while (t--) { clr0(u),clr0(v); scanf("%s", a); s = strlen(a); for (i = 0; i < s; ++i) ++u[id(a[i])]; scanf("%s", b); n = strlen(b); for (i = 0; i < n; ++i) ++v[id(b[i])]; if(solve()) puts("Yes"); else puts("No"); } return 0; }