所有元数从小到大排列,尝试插入1到9,插入前检查当前数字的个数,确保插入后不会超过4。一定会出现雀头,尝试去掉雀头再打牌,剩下的牌则看是否为刻子、顺子,是则打掉牌,再打剩下的牌。若所有的牌都能打完则当前插入的数可胡牌。
#include <stdio.h>
#include <iostream>
#include <vector>
#include <algorithm>
#include <set>
using namespace std;
bool is_hu(const vector<int>& vec)
{
//所有的牌都能打完则胡牌;
if(vec.size() == 0)
return true;
int n = vec.size();
multiset<int> m_set(vec.begin(),vec.end());
int count0 = m_set.count(vec[0]);
//没有现出过雀头并且第一个数出现2次或者以上;
if(n % 3 != 0 && count0 >= 2)
{
//试着将雀头打掉,看剩下的牌能否打完;
vector<int> tmp(vec.begin()+2,vec.end());
if(is_hu(tmp))
return true;
}
//如果第一个数字出现次数 >= 3,试着打掉这个刻子后看剩下的是否能够打完;
if(count0 >= 3)
{
vector<int> tmp(vec.begin()+3,vec.end());
if(is_hu(tmp))
return true;
}
//如果存在顺子,打掉顺子后剩下看是否能各牌;
if(m_set.find(vec[0]+1) != m_set.end() && m_set.find(vec[0]+2) != m_set.end())
{
vector<int> tmp(vec);
vector<int>::iterator iter = std::find(tmp.begin(),tmp.end(),vec[0]);
if(iter != tmp.end())
tmp.erase(iter);
iter = std::find(tmp.begin(),tmp.end(),vec[0]+1);
if(iter != tmp.end())
tmp.erase(iter);
iter = std::find(tmp.begin(),tmp.end(),vec[0]+2);
if(iter != tmp.end())
tmp.erase(iter);
if(is_hu(tmp))
return true;
}
return false;
}
int main()
{
vector<int> vec;
int n;
while(cin >> n)
vec.push_back(n);
for(int i=1;i<=9;i++)
{
vector<int> tmp(vec);
//最多只有四张相同的牌,插入后不能超过4,这里做下判断;
multiset<int> m_set(tmp.begin(),tmp.end());
if(m_set.count(i) >= 4)
{
continue;
}
tmp.push_back(i);
sort(tmp.begin(),tmp.end());
if(is_hu(tmp))
cout << i << " ";
}
return 0;
}
京公网安备 11010502036488号