japanese麻将什么玩意。。都没有豪华七对。。。

没什么难的 就是枚举搜索了

分三种类型的胡牌

f1是七对 f2是十三幺 f3是普通的胡牌 就先找一对 再找三个三个的

就是一直超时。。在峰峰的指导下加了好多剪枝 注释都标出来了。。这样才过 而且好慢。。

#include <iostream>
#include <cstring>
#include <string>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <map>
using namespace std; int cnt[40],res,ans[40];
map<string,int>mp;
void init()
{
mp["1m"]=1; mp["1s"]=11; mp["1p"]=21;
mp["2m"]=2; mp["2s"]=12; mp["2p"]=22;
mp["3m"]=3; mp["3s"]=13; mp["3p"]=23;
mp["4m"]=4; mp["4s"]=14; mp["4p"]=24;
mp["5m"]=5; mp["5s"]=15; mp["5p"]=25;
mp["6m"]=6; mp["6s"]=16; mp["6p"]=26;
mp["7m"]=7; mp["7s"]=17; mp["7p"]=27;
mp["8m"]=8; mp["8s"]=18; mp["8p"]=28;
mp["9m"]=9; mp["9s"]=19; mp["9p"]=29;
mp["1c"]=31;mp["2c"]=32; mp["3c"]=33;
mp["4c"]=34;mp["5c"]=35; mp["6c"]=36;
mp["7c"]=37;
} int f1()//7dui
{
int a=0;
for(int i=1;i<=38;i++)
{
if(cnt[i]==2) a++;
}
return a==7;
} int f2()//13yao
{
int i,j;
for(i=0;i<30;i+=10)
{
if(!cnt[i+1]||!cnt[i+9]) return 0;
for(j=2;j<9;j++)
if(cnt[i+j]) return 0;
}
for(i=31;i<=37;i++)
if(!cnt[i]) return 0;
return 1;
} int dfs()
{
int i;
if(res==0) return 1;
for(i=1;i<30;i++)
{
if(cnt[i]>=3)
{
cnt[i]-=3;
res-=3;
if(dfs()){
cnt[i]+=3;
res+=3;
return 1;
}
cnt[i]+=3;
res+=3;
}
}
for(i=1;i<30;i++)
{
if(cnt[i]&&cnt[i+1]&&cnt[i+2])
{
cnt[i]--;
cnt[i+1]--;
cnt[i+2]--;
res-=3;
if(dfs()){
cnt[i]++;
cnt[i+1]++;
cnt[i+2]++;
res+=3;
return 1;
}
cnt[i]++;
cnt[i+1]++;
cnt[i+2]++;
res+=3;
}
}
return 0;
} int f3()
{
int i;
for(i=1;i<38;i++)
if(cnt[i]>=2)
{
cnt[i]-=2;
res=12;
int ok=1;//这里再加一个剪枝 先找出连不成一句话的三个一样的
for(int j=31;j<=37;j++)
{
if(cnt[j]==3) res-=3;//减小dfs
else if(cnt[j]) {ok=0;break;}
}
if(!ok) {cnt[i]+=2;continue;}
if(dfs())
{
cnt[i]+=2;
return 1;
}
cnt[i]+=2;
}
return 0;
} int main()
{
int t,i,k;
char s[5];
init();
scanf("%d",&t);
while(t--)
{
memset(cnt,0,sizeof cnt);
for(i=0;i<13;i++)
{
scanf("%s",s);
cnt[mp[s]]++;
}
for(i=1,k=0;i<=37;i++)
{
if(i%10==0||cnt[i]==4) continue;//如果这张牌已经有四个就不用加啦
cnt[i]++;
if(cnt[i]==4&&!cnt[i-1]&&!cnt[i+1]){
cnt[i]--;//如果这张牌有四个 且相邻两个都没有 那一定不能胡
continue;
}
if(f2()){
ans[k++]=i;
cnt[i]--;
continue;
}
else if(cnt[i]==1&&!cnt[i-1]&&!cnt[i+1]){
cnt[i]--;//判断为不是十三幺后
continue;//如果这张牌只有一个 而且前后都没有 那一定不能胡
}
if(f1()||f3())
ans[k++]=i;
cnt[i]--;
}
if(k)
{
// sort(ans.begin(),ans.end());//mark
printf("%d",k);
for(i=0;i<k;i++)
{
if(ans[i]<10)
printf(" %dm",ans[i]%10);
else if(ans[i]<20)
printf(" %ds",ans[i]%10);
else if(ans[i]<30)
printf(" %dp",ans[i]%10);
else printf(" %dc",ans[i]%10);
}
putchar('\n');
}
else printf("Nooten\n");
}
return 0;
}

hdu4431 Mahjong 枚举搜索。。的更多相关文章

  1. HDU 4900 NO ACM NO LIFE(概率+枚举+搜索)(2014 Multi-University Training Contest 4)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4900 Problem Description There is an old country and ...

  2. uva 11210 Chinese Mahjong(暴力搜索)

    Chinese Mahjong Mahjong () is a game of Chinese origin usually played by four persons with tiles res ...

  3. hdu4431 Mahjong

    Mahjong Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submi ...

  4. Luogu 1764 翻转游戏 - 枚举 + 搜索

    题目描述 kkke在一个n*n的棋盘上进行一个翻转游戏.棋盘的每个格子上都放有一个棋子,每个棋子有2个面,一面是黑色的,另一面是白色的.初始的时候,棋盘上的棋子有的黑色向上,有的白色向上.现在kkke ...

  5. HDU - 4431 Mahjong (模拟+搜索+哈希+中途相遇)

    题目链接 基本思路:最理想的方法是预处理处所有胡牌的状态的哈希值,然后对于每组输入,枚举每种新加入的牌,然后用哈希检验是否满足胡牌的条件.然而不幸的是,由于胡牌的状态数过多(4个眼+一对将),预处理的 ...

  6. 枚举+搜索 hdu-4431-Mahjong

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4431 题目大意: 给一副牌,求出所有能糊的牌. 解题思路: 枚举每一张牌,看能不能糊. 因为一共只有 ...

  7. 【ACwing 95】费解的开关——枚举 + 搜索

    (题面来自ACwing) 你玩过"拉灯"游戏吗?25盏灯排成一个5x5的方形.每一个灯都有一个开关,游戏者可以改变它的状态.每一步,游戏者可以改变某一个灯的状态.游戏者改变一个灯的 ...

  8. HDU 4705 Y 树形枚举

    树形枚举--搜索 题目描述: 给你一棵树,要在一条简单路径上选3个不同的点构成一个集合,问能构成多少个不同的集合. 解法: 枚举所有结点,假设某个结点有n棵子树,每棵子树的结点个数分别为s1,s2,` ...

  9. 例 7-10 uva12212(迭代加深搜索)

    题意:对于一段数字,每次可以剪切一段连续的自然数,粘贴到任意部分,使其变成升序 思路: 考虑的是进行搜索,深搜并不能保证是最短,广搜感觉每层的情况太多. 迭代加深:枚举搜索深度,然后进行深搜. 这种方 ...

随机推荐

  1. winform程序中界面的跳转问题

    首先是我们进行窗口间的跳转,尤其注意的是winform程序里面的空间都是中线程安全的.但是注意的是如果你在一个线程中操纵另外的控件,这时候会提示你一个错误,这个错误的解决方法准备单独的在另一篇文章中来 ...

  2. java基础(死循环退出选项)

    java程序中为了程序正常运行,需要给无限循环加入一个退出选项,保证程序的可执行性. import java.util.Scanner; public class { public static vo ...

  3. 比较ArrayList和LinkedList

    比较一:添加内容 涉及方法:add public void add_test(){ List<Person> addlist = new ArrayList<Person>() ...

  4. POJ 1185 状态压缩DP(转)

    1. 为何状态压缩: 棋盘规模为n*m,且m≤10,如果用一个int表示一行上棋子的状态,足以表示m≤10所要求的范围.故想到用int s[num].至于开多大的数组,可以自己用DFS搜索试试看:也可 ...

  5. Linux环境下添加ftp账号步骤

    (1)远程登录Linux服务器所用的工具,免费开源,可以从网站上很容易就下载到. (2)打开putty,输入服务器IP,进入后按提示进入用户名和密码输入超级管理员 root,然后系统让输入密码,注意此 ...

  6. 【原创】Android 从一个Activity跳转到另外一个Activity

    Android四大组件activity使用,实现两个activity之间的跳转 基本流程:创建两个activity-将其中一个activity中组件作为事件源-通过组件事件的处理借助intent对象实 ...

  7. 我的接口框架---框架函数文件common.php

    <?php defined('JDHU') OR die('no allow access'); /** * 加载配置文件 */ function &get_config($replac ...

  8. [CSS]background背景

    css背景样式 序号  中文说明  标记语法  1  背景颜色  {background-color:数值}  2  背景图片  {background-image: url('imgpath/img ...

  9. base 使网页所有超链接都以新超链接的方式打开

    需求,网页有许多超链接,但是没有加 target="_blank",现在需要所有超链接都已新页面的方式打开 在head头添加 <base target="_blan ...

  10. Meditation Guide

    Meditation “Stop!!!” don’t we just scream[vi. 尖叫:呼啸:发出尖锐刺耳的声音:令人触目惊心 ] this in our minds when the da ...