牛客上的字节题

题目如下

雀魂启动!
小包最近迷上了一款叫做雀魂的麻将游戏,但是这个游戏规则太复杂,小包玩了几个月了还是输多赢少。
于是生气的小包根据游戏简化了一下规则发明了一种新的麻将,只留下一种花色,并且去除了一些特殊和牌方式(例如七对子等),具体的规则如下:
 
  1. 总共有36张牌,每张牌是1~9。每个数字4张牌。
  2. 你手里有其中的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哪个做雀头,都无法组成和牌的条件。
 
现在,小包从36张牌中抽取了13张牌,他想知道在剩下的23张牌中,再取一张牌,取到哪几种数字牌可以和牌。
用回溯去做,

能组合成刻子就组合成刻子,组合不成了,就把后面的x+1,x+2也给减去了

并且要求用数组去做,从1-9索引去遍历,而不是用去map再排序

题解如下

 

public static void main(String[] args) {

 

Scanner scanner = new Scanner(System.in);

 

String s = scanner.nextLine();
String[] num = s.split(" ");

 

int[] array = new int[9];
int[] helpArray = new int[9];
for (int i = 0; i < num.length; i++) {
array[Integer.parseInt(num[i])-1]++ ;
}
// 开始加数据
ArrayList<Integer> list = new ArrayList<>();
for (int i = 1; i <= 9; i++) {

 

if (array[i-1]<4){

 

System.arraycopy(array,0,helpArray,0,9);

 

//给这个地方加了数据了
helpArray[i-1]++;
if (canHu(helpArray,14,false)){
// 这个数据可以加进来
list.add(i);

 

}

 


}else {
// 不能加了
}

 


}
if (list.isEmpty()){
System.out.println(0);
}else {
for (int i = 0; i < list.size(); i++) {
System.out.print(list.get(i));
if (i!=list.size()-1){
System.out.print(" ");
}
}
}

 

 

 

 

 

}

 

/**
* 回溯去判断 一个个减去
* @param helpArray
* @param total 到0的时候可以推出去了
* @param hasHead
* @return
*/
private static boolean canHu(int[] helpArray, int total, boolean hasHead) {

 

if (total==0){
// 成功
return true;
}

 


if (!hasHead){
// 先找两个头

 


for (int i = 0; i < helpArray.length; i++) {
if (helpArray[i]>=2){
// 可以当头
helpArray[i]-=2;
if (canHu(helpArray,total-2,true)){
return true;
}
helpArray[i]+=2;

 


}
}
}else {
// 有头了
// 和牌
for (int i = 0; i < helpArray.length; i++) {
if (helpArray[i]>=3){
// 组合成刻子
helpArray[i]-=3;
if (canHu(helpArray,total-3,true)) {

 

return true;
}
helpArray[i]+=3;
}

 

// 不能用else 因为需要是否能够刻子和顺子都判断一次

 

if (i<7){
// 7 8 9 最大
if (helpArray[i]>0&&helpArray[i+1]>0&&helpArray[i+2]>0){
// 把它们三个组合成顺子

 

helpArray[i]--;
helpArray[i+1]--;
helpArray[i+2]--;
if (canHu(helpArray,total-3,true)){
return true;
}
helpArray[i]++;
helpArray[i+1]++;
helpArray[i+2]++;
}

 


}

 

 

 

}

 

 

 

 

 

 

 

}

 

 

 

 

 

 

 


return false;

 

}

 

posted @   故里oc  阅读(16)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示