字节跳动2019春招试题三——雀魂

字节跳动2019春招试题三——雀魂

题目来自牛客网,感谢!

从1~9每种4张共36张的麻将中取出13张,将能和牌的第14张牌的可能取值输出
满足以下条件能够和牌:

  • 有2张数字相同,称为雀头
  • 余下的12张构成4组顺子或刻子,顺子指形如123、567等,刻子指形如111、888等

输入格式:

第一行输入用空格分隔的13个数字
输入保证每个数字在1~9之间,且相同数字最多出现4次。

输出格式:

第一行输出1个或以上的数字,代表使牌面和牌的第14张牌的可能取值
若不存在,输出0;若多于1个,从小到大按序输出

输入范例:

1 1 1 1 2 2 3 3 5 6 7 8 9

输出范例:

4 7

由于数据局限在1~9,首先就考虑到用基数来处理数据。令1~9循环作为第14张牌进行和牌判定。
一开始在形为122333445的形式处有点纠结,因为这意味着数据量为3的时候不能直接消去,后来意识到基数按序消去的时候,顺子均会在顺子顺序里的第一个数处被检出并消去,因此3的情况只需考虑消去即可。
这里进行了第一轮测试,发现没考虑雀头。加上雀头之后整体的讨论变得非常复杂,用了偷懒的方式,检索基数,凡是检索到多于2的位置令其-2后再进行顺子刻子判定。
这里进行了第二轮测试,遇到了最后一个问题:由于未考虑到形为112233的形式,导致武断地认定顺刻判定时只有2的时候是必然不成顺刻的。意识到这个问题并修改,成功通过了OJ。

我的代码实现:

import java.util.Scanner;
 
public class Majiang{
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int[] a = new int[13];
        for (int i = 0; i < 13; i++)
            a[i] = sc.nextInt();
        sc.nextLine();
        sc.close();
        int[] num = new int[9];
        for (int i = 0; i < 9; i++)
            num[i] = 0;
        for (int i = 0; i < 13; i++)
            num[a[i] - 1]++;
        int trigger = 0;
        for (int i = 0; i < 9; i++) {
            if (num[i] == 4)
                continue;
            if (check2(num, i)) {
                if (trigger > 0)
                    System.out.print(" ");
                System.out.print(i + 1);
                trigger++;
            }
        }
        if (trigger == 0)
            System.out.println(0);
    }
 
    public static boolean check2(int[] num, int p) {
        int[] x = new int[9];
        for (int i = 0; i < 9; i++)
            x[i] = num[i];
        x[p]++;
        for (int i = 0; i < 9; i++)
            if (x[i] >= 2)
                if (check(x, i))
                    return true;
        return false;
 
    }
 
    public static boolean check(int[] num, int p) {
        int[] x = new int[9];
        for (int i = 0; i < 9; i++)
            x[i] = num[i];
        x[p] -= 2;
        for (int i = 0; i < 9; i++) {
            if (x[i] >= 3)
                x[i] -= 3;
            if (x[i] == 2)
                if (i + 2 < 9 && x[i + 1] > 0 && x[i + 2] > 0) {
                    x[i]--;
                    x[i + 1]--;
                    x[i + 2]--;
                } else
                    return false;
            if (x[i] == 1)
                if (i + 2 < 9 && x[i + 1] > 0 && x[i + 2] > 0) {
                    x[i]--;
                    x[i + 1]--;
                    x[i + 2]--;
                } else
                    return false;
        }
 
        return true;
    }
}

PS:写的时候不知道麻将的日语说法是什么,印象中好像是麻将发音的片假名,姑且写了个Majiang作为类名,不过也不打算去查了哈哈哈

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值