枚举+搜索 hdu-4431-Mahjong
2013-08-18 19:37
141 查看
题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=4431
题目大意:
给一副牌,求出所有能糊的牌。
解题思路:
枚举每一张牌,看能不能糊。
因为一共只有14张牌,每次依据将,去掉三张牌,判断最后两张牌是否一样。
七对和十三幺单独考虑,
注意:
1、1p 1p 1s 9s 1m 9m 1c 2c 3c 4c 5c 6c 7c 这样的也可以糊9p。
2、七对时,要为不同的牌,1s 1s 1s 1s 不能糊七对。
剪枝:
1、对于不是c色牌,能糊的牌一定出现在手牌或+1,-1同色牌中,所以只用枚举这些可以糊的牌即可。
2、对于单独的一张牌,左右相邻没有同色牌时,不能糊。
贴几组测试数据:
20
1p 2p 3p 7p 8p 9p 1s 2s 3s 1c 1c 2c 2c
2 1c 2c
1p 2p 3p 3p 3p 3p 4p 5p 1m 2m 3m 4m 5m
2 3m 6m
1s 2s 3s 2c 2c 2c 2p 3p 5m 6m 7m 1p 1p
2 1p 4p
1p 1p 2p 3p 4s 5s 6s 7c 7c 3s 3s 2m 2m
Nooten
1p 1p 1p 2p 2p 3p 3p 4p 4p 5p 6p 7p 8p
6 2p 3p 5p 6p 8p 9p
1p 2p 3p 3p 3p 4p 5p 1m 2m 3m 4m 5m 6m
2 3p 6p
1p 2p 3p 3p 3p 3p 4p 5p 1m 2m 3m 4m 5m
2 3m 6m
1p 2p 3p 3p 3p 3p 4p 5p 6p 1m 2m 3m 4m
2 1m 4m
1c 2c 3c 4c 5c 6c 7c 1p 9p 1m 9m 1s 9s
13 1m 9m 1s 9s 1p 9p 1c 2c 3c 4c 5c 6c 7c
1p 1p 3p 2p 5p 2p 6p 7p 3p 4p 5p 6p 4p
3 1p 4p 7p
1p 1p 2p 3p 2p 3p 4p 4p 5p 5p 6p 7p 7p
2 3p 6p
1p 1p 9p 9p 1m 1m 9m 9m 1s 9s 1s 9s 7c
1 7c
1p 1p 1p 1p 1m 1m 1m 1s 9s 1c 1c 1s 9s
Nooten
1p 1p 1s 9s 1m 9m 1c 2c 3c 4c 5c 6c 7c
1 9p
代码:
http://acm.hdu.edu.cn/showproblem.php?pid=4431
题目大意:
给一副牌,求出所有能糊的牌。
解题思路:
枚举每一张牌,看能不能糊。
因为一共只有14张牌,每次依据将,去掉三张牌,判断最后两张牌是否一样。
七对和十三幺单独考虑,
注意:
1、1p 1p 1s 9s 1m 9m 1c 2c 3c 4c 5c 6c 7c 这样的也可以糊9p。
2、七对时,要为不同的牌,1s 1s 1s 1s 不能糊七对。
剪枝:
1、对于不是c色牌,能糊的牌一定出现在手牌或+1,-1同色牌中,所以只用枚举这些可以糊的牌即可。
2、对于单独的一张牌,左右相邻没有同色牌时,不能糊。
贴几组测试数据:
20
1p 2p 3p 7p 8p 9p 1s 2s 3s 1c 1c 2c 2c
2 1c 2c
1p 2p 3p 3p 3p 3p 4p 5p 1m 2m 3m 4m 5m
2 3m 6m
1s 2s 3s 2c 2c 2c 2p 3p 5m 6m 7m 1p 1p
2 1p 4p
1p 1p 2p 3p 4s 5s 6s 7c 7c 3s 3s 2m 2m
Nooten
1p 1p 1p 2p 2p 3p 3p 4p 4p 5p 6p 7p 8p
6 2p 3p 5p 6p 8p 9p
1p 2p 3p 3p 3p 4p 5p 1m 2m 3m 4m 5m 6m
2 3p 6p
1p 2p 3p 3p 3p 3p 4p 5p 1m 2m 3m 4m 5m
2 3m 6m
1p 2p 3p 3p 3p 3p 4p 5p 6p 1m 2m 3m 4m
2 1m 4m
1c 2c 3c 4c 5c 6c 7c 1p 9p 1m 9m 1s 9s
13 1m 9m 1s 9s 1p 9p 1c 2c 3c 4c 5c 6c 7c
1p 1p 3p 2p 5p 2p 6p 7p 3p 4p 5p 6p 4p
3 1p 4p 7p
1p 1p 2p 3p 2p 3p 4p 4p 5p 5p 6p 7p 7p
2 3p 6p
1p 1p 9p 9p 1m 1m 9m 9m 1s 9s 1s 9s 7c
1 7c
1p 1p 1p 1p 1m 1m 1m 1s 9s 1c 1c 1s 9s
Nooten
1p 1p 1s 9s 1m 9m 1c 2c 3c 4c 5c 6c 7c
1 9p
代码:
#include<iostream> #include<cmath> #include<cstdio> #include<cstdlib> #include<string> #include<cstring> #include<algorithm> #include<vector> #include<map> #include<set> #include<stack> #include<list> #include<queue> #define eps 1e-6 #define INF 0x1f1f1f1f #define PI acos(-1.0) #define ll __int64 #define lson l,m,(rt<<1) #define rson m+1,r,(rt<<1)|1 //#pragma comment(linker, "/STACK:1024000000,1024000000") using namespace std; /* freopen("data.in","r",stdin); freopen("data.out","w",stdout); */ map<char,int>myp; int save[5][15],cnt; char sa[5]; char pp[4]={'m','s','p','c'}; bool flag,ans[40],hav[40]; void juqi(int a) //判断是否是七对 { for(int i=0;i<34;i++) { int x=i/9,y=i%9; if(!save[x][y]) continue; if(save[x][y]!=2) return ; } //printf("qidui yes\n"); ++cnt,ans[a]=true; return ; } void jushi(int a) //判断是否是十三幺 { for(int i=0;i<3;i++) { if(save[i][0]!=1&&save[i][0]!=2) return ; if(save[i][8]!=1&&save[i][8]!=2) return ; for(int j=1;j<8;j++) if(save[i][j]) return ; } for(int i=0;i<7;i++) if(save[3][i]!=1&&save[3][i]!=2) return ; ++cnt,ans[a]=true; return ; } void dfs(int num,int val) { if(flag) return ; if(num==2) { for(int i=0;i<4;i++) { for(int j=0;j<=((i==3)?6:8);j++) if(save[i][j]==2) //最后两张牌,肯定是一样的才可能糊 { flag=true; if(!ans[val]) ++cnt,ans[val]=true; return ; } else if(save[i][j]) return ; } } for(int i=0;i<4;i++) { for(int j=0;j<(i==3?7:9);j++) { if(save[i][j]>=3) //三张一样的牌 { save[i][j]-=3; dfs(num-3,val); save[i][j]+=3; if(flag) return ; } if(!j||j==8||i==3) continue; if(save[i][j]&&save[i][j-1]&&save[i][j+1])//连续三张同色牌,注意c牌不行 { save[i][j]--,save[i][j-1]--,save[i][j+1]--; dfs(num-3,val); save[i][j]++,save[i][j-1]++,save[i][j+1]++; if(flag) return ; } } } } bool iscan() { for(int i=0;i<3;i++) { if(save[i][0]==1&&save[i][1]==0) return false; int j; for(j=1;j<=7;j++) //当为只有1张牌,且左右没牌 { if(save[i][j]==1&&save[i][j-1]==0&&save[i][j+1]==0) return false; } if(save[i][j]==1&&save[i][j-1]==0) return false; } for(int i=0;i<7;i++) if(save[3][i]==1) return false; return true; } int main() { myp['m']=0,myp['s']=1,myp['p']=2,myp['c']=3; int t; scanf("%d",&t); while(t--) { memset(save,0,sizeof(save)); memset(ans,false,sizeof(ans)); memset(hav,false,sizeof(hav)); for(int i=1;i<=13;i++) { scanf("%s",sa); save[myp[sa[1]]][*sa-'0'-1]++; int xx=myp[sa[1]]*9+*sa-'0'-1; hav[xx]=true; //hav为能够糊的牌 if(xx%9) //当然c牌有些不能糊也算进去了,不要紧 { if(xx%9==8) hav[xx-1]=true; else hav[xx-1]=hav[xx+1]=true; } else hav[xx+1]=true; } cnt=0; for(int i=0;i<34;i++) { if(save[i/9][i%9]>=4) //这张牌已经没有了 continue; save[i/9][i%9]++; jushi(i); if(!hav[i]||!iscan()) //两个剪枝 { save[i/9][i%9]--; continue; } juqi(i); flag=false; dfs(14,i); save[i/9][i%9]--; } if(!cnt) { printf("Nooten\n"); continue; } printf("%d",cnt); for(int i=0;i<34;i++) { if(ans[i]) printf(" %d%c",i%9+1,pp[i/9]); } putchar('\n'); } return 0; }
相关文章推荐
- 枚举+搜索 hdu-4431-Mahjong
- hdu 4431 Mahjong (模拟,枚举+dfs)
- HDU 4431 Mahjong 2012天津A题 模拟题
- hdu 4431 Mahjong,uva 11210 chinese Mahjong,麻将,超快的解法。。
- HDU 4431 Mahjong (DFS,暴力枚举,剪枝)
- HDU 4431 Mahjong
- HDU_4431_Mahjong(模拟)
- HDU 4431 Mahjong 搜索 模拟
- hdu 4431 Mahjong(dfs+模拟)
- HDU 4431 Mahjong(模拟题)
- hdu 4431 Mahjong 模拟
- HDU 4431 Mahjong (麻将、神坑模拟题)
- hdu 4431 Mahjong
- hdu 4431 Mahjong (模拟)
- HDU 4431 Mahjong 2012天津A题 模拟题
- hdu - 4431 - Mahjong - 模拟
- HDU 4431 Mahjong(枚举,模拟)
- HDU 4431 Mahjong
- HDU 4431 Mahjong(枚举+模拟)(2012 Asia Tianjin Regional Contest)
- HDU 4431 Mahjong(12天津A题)#by zh