2.字节跳动2019雀魂启动

雀魂启动

话不多说先放题
时间限制:1秒
空间限制:32768K
小包最近迷上了一款叫做雀魂的麻将游戏,但是这个游戏规则太复杂,小包玩了几个月了还是输多赢少。
于是生气的小包根据游戏简化了一下规则发明了一种新的麻将,只留下一种花色,并且去除了一些特殊和牌方式(例如七对子等),具体的规则如下:
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张牌中,再取一张牌,取到哪几种数字牌可以和牌。
输入描述:
输入只有一行,包含13个数字,用空格分隔,每个数字在1~9之间,数据保证同种数字最多出现4次。
输出描述:
输出同样是一行,包含1个或以上的数字。代表他再取到哪些牌可以和牌。若满足条件的有多种牌,请按从小到大的顺序输出。若没有满足条件的牌,请输出一个数字0
输入例子1:
1 1 1 2 2 2 5 5 5 6 6 6 9
输出例子1:
9
例子说明1:
可组成1,2,6,7的4个刻子和9的雀头
输入例子2:
1 1 1 1 2 2 3 3 5 6 7 8 9
输出例子2:
4 7
例子说明2:
用1做雀头,组123,123,567或456,789的四个顺子
输入例子3:
1 1 1 2 2 2 3 3 3 5 7 7 9
输出例子3:
0

例子说明3:
来任何牌都无法和牌
题目地址:https://www.nowcoder.com/question/next?pid=16516564&qid=362291&tid=27407896(一般打不开的,可自行到牛客网看)

解题思路

22:40
首先,我看到题目,我就吓到了,我以为是要把麻将的胡法给总结出来,结果剩下12张牌可以组成4个顺子或刻子,突然就把难度给减低了许多,首先,四个刻子+一个雀头应该是最简单的了,大家说对不对,我想到最简单的方法就是定义一个length=9的数组,数组下标依次对应着0-9,初始化都为0,然后遍历13个数,例如第一个数是1,数组【1-1】+1(因为数组从0开始),然后遍历该数组,如果所有=3的有3个,=2的有两个,即可输出=2的两个数,如果=3的有4个,那么输出=1的。
23:25 //code能力真的辣鸡
来,看代码
在这里插入图片描述
今天发布的时候,我突然想到,我好像忘了些东西,就是我是要判断一些这13个数的合法性,就是是否是0-9的36个数字,没事,当日事当日清,今天已经是全新的一天了,我们继续吧

那么现在就到了判断顺子,那么问题来了,我没做过这种题,据我所知,有一种基础题就是讲,如何去判断连续数的,现在我们不看答案,先自己想想。
不懂的时候,我们就一步一步来,首先找到顺子的规律,规律就是,他们三个是++的关系,
那么我们可以假装 输入的数组是从小到大排序,那么我们先判断第一个数,然后记录下来,然后判断第二个数,是否是++,如果是就继续记录下来,继续判断第三个数,如果还是++,那么这三个数就是一个顺子。
我的想法就是,找到一个顺子就消掉,然后继续下一步操作。
然后这样带来了一个问题,如果这三个数,中间缺了一个,例如1 3 4 5,那么按照以上思路,就会判断错误了。
思路二:
先去掉可能的雀头,雀头,可以通过上面刻子得出,因为顺子的判断在刻子后面,那么这样就省了一步功夫
去掉雀头,然后把11位数,从小到大,分别获取3个数,这3个数有一个限制,例如,如果a[0]==a1,那么就继续找a[2],判断是否为++,如果找到3个,就把这三个数在数组中置0,然后继续第二个顺子的判断,照理,在过程中,如果发现a[0]=1,a[1]=3,即a[0]+2=a[3],那么就要returnA数组添加一个a[0]++的数了,这也是要输出的那个数,这时,也把a[0]和a[1]置0,如果循环中出现returnA[1]!=0,即可结束循环,java就是break.
23:49
还是用代码展示吧
写完代码已经是00:06了
在这里插入图片描述
上面是一个未完成品,因为写着写着,我发现,这个思路非常的麻烦,或者说,思路歪了,我这样相当于穷举了所有可能的胡法,就是一个暴力解法,麻烦的同时还很不友好,所以,我决定。。。
不是看答案,你个臭不要脸,再想想,不然我的脑洞时刻就没办法了

脑洞时刻

开始疯狂暗示自己,自己是可以的。
正的不行,我们反着来,穷举所有不成立的可能性,例如刻子还是一样的容易判断,就通过第一个demo统计出来的即可, 还是第二种顺子的判断,至少有两组数据是noShunzi的,noShunzi在代码中(代表缺的值)就是12/1*3/23这三种情况,通过每三个数符合shunzi就消掉,每两个数符合noShunzi也消掉,如果noShunzi[].length>1,即可返回0,不然就是返回noShunzi的,然后因为从左往右跟从右往左,得到的顺子组合会不一样,那么我们再从右往左计算一次,如果得出的noShunzi.length还是大于1,那么,就可以返回0了。
实话说,这个反的思路不够彻底,首先就是刻子和顺子分开判断了,获取最优解会是两个情况一起判断,但是我转头一想,题目只给出了两个情况,估计就是为了让我们做正向判断吧,如果是真实的麻将,反向判断应该会更好,真实的麻将实际返回时还要返回时吃胡还是自摸等情况,那么还是得正向判断,因为真实的麻将,可不是,return 0或1了,应该是return “自摸”,”大四喜”这些,其实这样分类返回,我觉得,虽然工程量大了,但是整个流程分解下来,就会比较简单,你只需要判断这副牌是不是大四喜/自摸即可,这样一个麻将算法可以分配给多个开发去开发,人多力量大,众人拾柴火焰嘛
0:25,准备看iphone发布会

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值