小包最近迷上了一款叫做雀魂的麻将游戏,但是这个游戏规则太复杂,小包玩了几个月了还是输多赢少。
于是生气的小包根据游戏简化了一下规则发明了一种新的麻将,只留下一种花色,并且去除了一些特殊和牌方式(例如七对子等),具体的规则如下:
总共有36张牌,每张牌是1~9。每个数字4张牌。
你手里有其中的14张牌,如果这14张牌满足如下条件,即算作和牌
例如:
1 1 1 2 2 2 6 6 6 7 7 7 9 9
可以组成1,2,6,7的4个刻子和9的雀头,可以和牌
1 1 1 1 2 2 3 3 5 6 7 7 8 9
用1做雀头,组123,123,567,789的四个顺子,可以和牌
1 1 1 2 2 2 3 3 3 5 6 7 7 9
无论用1 2 3 7哪个做雀头,都无法组成和牌的条件。
现在,小包从36张牌中抽取了13张牌,他想知道在剩下的23张牌中,再取一张牌,取到哪几种数字牌可以和牌。
输入1 1 1 2 2 2 5 5 5 6 6 6 9
输出9
可以组成1,2,6,7的4个刻子和9的雀头
输入1 1 1 1 2 2 3 3 5 6 7 8 9
输出4 7
用1做雀头,组123,123,567或456,789的四个顺子
输入1 1 1 2 2 2 3 3 3 5 7 7 9
输出0
来任何牌都无法和牌
备注:请不要根据自己的常识为题目增加未提及的条件。对于20%的数据,保证和牌时一定是4个刻子+雀头的形式
代码:
#include
#include
#include
using namespace std;
bool ishu(vector<int>num)
{
if (num.empty())return true;
int count0 = 0;
for(int i=0;i<num.size();++i){
if (num[0] == num[i])
++count0;
else break;
}//第一个元素出现的次数为count0
if (num.size() % 3 != 0 && count0 >= 2){
//尝试将第一个元素作为雀头
vector<int> newnum(num.begin() + 2, num.end());
if (ishu(newnum))
return true;
}
//若第一个元素不能作为雀头,且大于三次
if (count0 >= 3){
vector<int> newnum(num.begin() + 3, num.end());
if (ishu(newnum))//将重复的第一个元素去掉,遍历到第二个元素
return true;
}
//如果元素的后两个元素都存在,那么把后两个元素都删掉一个
if(count(num.begin(),num.end(),num[0]+1)>0 && count(num.begin(), num.end(), num[0] + 2)>0)
{
vector<int> newnum(num.begin() + 1, num.end());
newnum.erase(find(newnum.begin(), newnum.end(), num[0] + 1));
newnum.erase(find(newnum.begin(), newnum.end(), num[0] + 2));
if (ishu(newnum))
return true;
}
return false;
}
bool hupai(vector<int>num, int n)
{
if (count(num.begin(), num.end(), n) == 4)//如果n已经出现4次了,那么不能再加n
return false;
num.push_back(n);//将尝试的元素加入到数组中
sort(num.begin(),num.end());
return ishu(num);//判断是否胡牌
}
int main()
{
vector<int> num;
vector<int> res;
for (int i = 0; i < 13; ++i){
int tmp;
cin >> tmp;
num.push_back(tmp);
}
for (int n = 1; n < 10; ++n){
if (hupai(num, n))//挨个试是否能胡牌,总共也就10种选择
res.push_back(n);
}
if (res.empty())
cout << 0;
else
for (int i = 0; i < res.size(); ++i)
cout << res[i]<<" ";
}
algorithm头文件定义了一个count的函数,其功能类似于find。
这个函数使用一对迭代器和一个值做参数,返回这个值出现次数的统计结果。
count(first,last,value);
first是容器的首迭代器,last是容器的末迭代器,value是询问的元素。
#include
#include
#include
using namespace std;
int main(){
//count函数的用法
vector<int> v(10,1);
int a[10] = { 1, 2, 3, 4, 4, 4, 4 };
//向量计数
cout << count(v.begin(), v.end(), 1) << endl;
//数组计数
cout << count(a, a + 10, 1) << endl;
return 0;
}
count(first,last,pred);
first是容器的首迭代器,last是容器的末迭代器,pred是元素被计数的满足条件。
可以用来在序列中统计与某谓词匹配的次数。
#include
#include
#include
bool greater10(int value){
return value >10;
}
int main(){
using namespace std;
vector<int> v1;
v1.push_back(10);
v1.push_back(20);
v1.push_back(10);
result1 = count_if(v1.begin(), v1.end(), greater10);
cout << "大于10的元素个数为: "<< result1<< endl;
}
find函数使用一对迭代器和一个值做参数,返回这个值第一次出现的位置。
find(first,last,value);
#include
#include
#include
using namespace std;
int main(){
vector<string> m;
m.push_back("hello");
if (find(m.begin(), m.end(), "hello") == m.end())
cout << "no" << endl;
else
cout << "yes" << endl;
}
c.erase(p)
删除迭代器p所指向的元素,返回一个指向被删元素之后元素的迭代器,若p指向尾元素,则返回尾后迭代器,若p是尾后迭代器,则会产生未定义行为。