[字节跳动编程题]雀魂启动!

1. 输入描述

总共有36张牌,每张牌是1-9。每个数字4张牌。输入只有一行,包含13个代表着13张牌的数字,用空格分隔,每个数字在1~9之间,数据保证同种数字最多出现4次。

2. 输出描述

输出同样是一行,包含1个或以上的数字。代表他再取到哪些牌可以和牌。若满足条件的有多种牌,请按从小到大的顺序输出。若没有满足条件的牌,请输出一个数字0,其中和牌的条件如下:

  • 14张牌中有2张相同数字的牌,称为雀头。
  • 除去上述2张牌,剩下12张牌可以组成4个顺子或刻子。顺子的意思是递增的连续3个数字牌(例如234,567等),刻子的意思是相同数字的3个数字牌(例如111,777)

3. 思路描述

从1到9九个数字进行遍历,判断当前已有的十三张牌中当前数字的牌是否已有四张,若没有则加入并且判断是否能满足条件,和了就将当前数字加入最终答案中并尝试下一个数字,若当前数字已有四张则跳过并尝试下一个数字。

而判断是否能满足条件的方法通过回溯法来实现,思路如下图:

是否已选出雀头
尝试抽出三张相同的数字或者尝试抽出三张连续的数字
判断剩下的牌是否满足要求
尝试抽出两张相同的牌做为雀头

4. 代码实现

import java.util.Scanner;

public class Main{
    private static boolean pass(boolean hadHeader,int count,int[] poker){
        if(count==0){
            return true;
        }
        if(hadHeader){
            for(int i=0;i<9;i++){
                if(poker[i]>2){
                    poker[i]-=3;
                    if(pass(true,count-3,poker)){
                        return true;
                    }
                    poker[i]+=3;
                }
                if(i<7&&poker[i]>0&&poker[i+1]>0&&poker[i+2]>0){
                    poker[i]--;
                    poker[i+1]--;
                    poker[i+2]--;
                    if(pass(true,count-3,poker)){
                        return true;
                    }
                    poker[i]++;
                    poker[i+1]++;
                    poker[i+2]++;
                }
            }
            return false;
        }else{
            for(int i=0;i<9;i++){
                if(poker[i]>1){
                    poker[i]-=2;
                    if(pass(true,count-2,poker)){
                        return true;
                    }
                    poker[i]+=2;
                }
            }
            return false;
        }
    }

    private static void copyArray(int[] arrayA,int[] arrayB){
        for(int i=0;i<9;i++){
            arrayA[i]=arrayB[i];
        }
    }

    public static void main(String[] args){
        /*
        * enter data to int array poker
        */
        StringBuffer result=new StringBuffer();
        Scanner scan=new Scanner(System.in);
        String[] temp=scan.nextLine().split(" ");
        int[] poker=new int[9],pokerBackup=new int[9];
        for(int i=0;i<13;i++){
            poker[Integer.parseInt(temp[i])-1]++;
        }

        for(int i=0;i<9;i++){
            copyArray(pokerBackup,poker);
            if(poker[i]<4){
                poker[i]++;
                if(pass(false,14,poker)){
                    if(result.length()!=0){
                        result.append(" ");
                    }
                    result.append(String.valueOf(i+1));
                }
                poker[i]--;
            }
            copyArray(poker,pokerBackup);
        }

        if(result.length()==0){
            System.out.println("0");
        }else{
            System.out.println(result.toString());
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值