10.26T3 模拟+爆搜
#3858 麻将
描述
输入
输入仅一行14张牌,用空格隔开。1..9表示牌上数字,w、p、s分别表示万、筒、条,如1s表示一条。
输出
输出仅一行两个整数用空格隔开,分别表示打出第几张牌会使得你听得牌的张数最多以及最多听多少张牌,如果有多张牌使得打出后听得牌一样多,输出标号最靠前的。
提示
【样例1说明】
无论是打出1s还是4s都是听3p和7p,而3p共有4张,手中已经有2张,牌堆中还剩2张,7p也有4张,手中已经有2张,牌堆中还剩2张,所以打出1s听4张。
mahjong.in
1s 1s 1s 2s 3s 4s 5s 6s 6p 6p 7p 8p 8p 9p
mahjong.out
12 10
【样例2说明】
打出6p或9p听7p共3张,打出8p听1s、4s、7s、6p共10张。
【数据范围及约定】
对于30%的数据,胡牌牌型中的句子只会是三张相同的牌。
对于另外20%的数据,14张手牌同属于万、筒、条其中的某一种。
注意不能消的时候看到三个一样就直接消,会出问题的
1 2 3 3 3 4 4 5
就可以卡掉贪心的
所以此题直接暴力枚举将牌和句子xjb搜下去就可以了
code:
1 #include<iostream> 2 #include<cstdio> 3 #include<string> 4 #include<algorithm> 5 #include<cstring> 6 #define N 50 7 using namespace std; 8 int num[15],co[15]; 9 int vis[15]; 10 int now=0; 11 struct node { 12 int dianshu,huase; 13 } e[N]; 14 bool cmp(const node&a,const node &b) { 15 if(a.huase==b.huase)return a.dianshu<b.dianshu; 16 return a.huase<b.huase; 17 } 18 int nownum[20],nowco[20]; 19 int temppai[4][15]; 20 bool dfs(int rest) { //搜索句子 21 if(rest==0)return true;//搜索成功 22 for(int i=1;i<=3;i++){ 23 for(int j=1;j<=9;j++){ 24 if(temppai[i][j]>=3){ 25 temppai[i][j]-=3; 26 if(dfs(rest-3))return true; 27 temppai[i][j]+=3; 28 } 29 } 30 } 31 for(int i=1;i<=3;i++){ 32 for(int j=1;j<=9;j++){ 33 if(temppai[i][j]&&temppai[i][j+1]&&temppai[i][j+2]){ 34 temppai[i][j]--; 35 temppai[i][j+1]--; 36 temppai[i][j+2]--; 37 if(dfs(rest-3))return true; 38 temppai[i][j]++; 39 temppai[i][j+1]++; 40 temppai[i][j+2]++; 41 } 42 } 43 } 44 return false; 45 } 46 bool judge() { 47 memset(temppai,0,sizeof temppai); 48 // for(int i=1;i<=14;i++)cout<<nownum[i]<<" "; 49 // cout<<'\n'; 50 // for(int i=1;i<=14;i++)cout<<nowco[i]<<" "; 51 // cout<<'\n'<<'\n'; 52 for(int i=1; i<=14; i++)temppai[nowco[i]][nownum[i]]++; 53 for(int i=1; i<=3; i++) { 54 for(int j=1; j<=9; j++) { //搜索将牌 55 if(temppai[i][j]>=2) { 56 temppai[i][j]-=2; 57 if(dfs(12))return true; 58 temppai[i][j]+=2; 59 } 60 } 61 } 62 return false; 63 } 64 int pai[4][10]; 65 int main() { 66 // freopen("mahjong.in","r",stdin); 67 // freopen("mahjong.out","w",stdout); 68 for(int i=1; i<=3; i++) {//花色 69 for(int j=1; j<=9; j++) {//点数 70 pai[i][j]=4; 71 } 72 } 73 for(int i=1; i<=14; i++) {//读入每一张牌 74 string k; 75 cin>>k; 76 num[i]=k[0]-'0'; 77 if(k[1]=='s')pai[1][num[i]]--,co[i]=1; 78 if(k[1]=='w')pai[2][num[i]]--,co[i]=2; 79 if(k[1]=='p')pai[3][num[i]]--,co[i]=3; 80 nownum[i]=num[i],nowco[i]=co[i]; 81 } 82 // for(int i=1;i<=14;i++)cout<<nownum[i]<<" "; 83 // cout<<'\n'; 84 // for(int i=1;i<=14;i++)cout<<nowco[i]<<" "; 85 // cout<<'\n'; 86 int t,max0=-1; 87 for(int i=1; i<=14; i++) {//枚举每一张牌 88 now=0; 89 //pai[co[i]][num[i]]--; 90 for(int j=1; j<=3; j++) {//枚举填进去的牌 91 for(int k=1; k<=9; k++) {//枚举点数 92 if(pai[j][k]) {//如果还有这张牌 93 nownum[i]=k,nowco[i]=j;//当前这一张牌的点数 94 int t=judge(); 95 // cout<<t<<'\n'; 96 // if(t)system("pause"); 97 if(t)now+=pai[j][k]; 98 } 99 } 100 } 101 //pai[co[i]][num[i]]++; 102 nownum[i]=num[i],nowco[i]=co[i]; 103 if(now>max0) { 104 max0=now; 105 t=i; 106 } 107 } 108 cout<<t<<" "<<max0; 109 return 0; 110 }
over