字节跳动—雀魂启动
一、题目描述#
小包最近迷上了一款叫做雀魂的麻将游戏,但是这个游戏规则太复杂,小包玩了几个月了还是输多赢少。
于是生气的小包根据游戏简化了一下规则发明了一种新的麻将,只留下一种花色,并且去除了一些特殊和牌方式(例如七对子等),具体的规则如下:
总共有36张牌,每张牌是1~9。每个数字4张牌。
你手里有其中的14张牌,如果这14张牌满足如下条件,即算作和牌
14张牌中有2张相同数字的牌,称为雀头。
除去上述2张牌,剩下12张牌可以组成4个顺子或刻子。顺子的意思是递增的连续3个数字牌(例如234,567等),刻子的意思是相同数字的3个数字牌(例如111,777)
例如:
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哪个做雀头,都无法组成和牌的条件。
1
2
3
现在,小包从36张牌中抽取了13张牌,他想知道在剩下的23张牌中,再取一张牌,取到哪几种数字牌可以和牌。
输入描述:
输入只有一行,包含13个数字,用空格分隔,每个数字在1~9之间,数据保证同种数字最
多出现4次。
1
2
输出描述:
输出同样是一行,包含1个或以上的数字。代表他再取到哪些牌可以和牌。若满足条件的有
多种牌,请按从小到大的顺序输出。若没有满足条件的牌,请输出一个数字0
1
2
二、分析#
首先清楚和牌的条件:1.两张相同的牌组成雀头。2.剩下的牌组成刻子或顺子
现在你有13张牌,在剩下的牌中选一张尽可能使手中的牌变成和牌
我们既然不知道怎么选择,那么就从1到9枚举所有的可能,记录结果即可
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
inline bool ishu(vector<int>num)
{
if(num.empty())
return true;
int count0 = 0;
//统计牌集合中第一张牌上数字在整个牌集合中出现的次数count0
count0 = count(num.begin(),num.end(),num[0]);
//雀头
//num.size()%3 != 0是用来判断一旦选了雀头下次就不能选了
//因为牌共有14张,要么去掉雀头两张剩12张(12 % 3 == 0)
//要么去掉顺子或刻子3张还剩11张(11 % 3 != 0)
//count0 >= 2是用来判断第一张牌数量是否大于等于2(雀头是2张)
if(num.size()%3 != 0 && count0 >= 2)
{
//去掉雀头的两张相同的牌继续递归判断
vector<int> newnum(num.begin() + 2,num.end());
if(ishu(newnum))
return true;
}
//刻子
//第一张牌的数量大于等于3张才有可能是刻子
if(count0 >= 3)
{
//去掉刻子的3张相同的牌继续判断
vector<int> newnum(num.begin()+3,num.end());
if(ishu(newnum))
return true;
}
//顺子
//注意走到这里并不代表count0 == 1,(牌面是1---9,所以可以直接进行+1来判断)
//如果下一张牌和下下一张牌的数量出现的次数超过一,那么这种情况是有可能构成顺子的
if(count(num.begin(),num.end(),num[0] + 1) > 0 &&
count(num.begin(),num.end(),num[0] + 2) > 0)
{
//找到构成顺子的3张牌,删掉继续判断
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;
}
//num是原本牌的集合,x是枚举的牌
inline bool hupai(vector<int> num,int x)
{
//过滤
if(count(num.begin(),num.end(),x) == 4)
return false;
//放到牌的集合当中
num.push_back(x);
//进行一次排序
sort(num.begin(),num.end());
//进行判断
return ishu(num);
}
int main()
{
vector<int> num(13),ans;
for(int i = 0;i < 13;++i)
{
cin>>num[i];
}
for(int i = 1;i <= 9;++i)
{
if(hupai(num,i))
ans.push_back(i);
}
if(ans.size() == 0)
puts("0");
else
{
for(int i = 0;i < ans.size();++i)
cout<<ans[i]<<" ";
}
return 0;
}
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战