前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >字节跳动2019年算法笔试题,你可以搞定吗?

字节跳动2019年算法笔试题,你可以搞定吗?

作者头像
TechFlow-承志
发布于 2021-01-08 07:22:45
发布于 2021-01-08 07:22:45
1.2K00
代码可运行
举报
文章被收录于专栏:TechFlowTechFlow
运行总次数:0
代码可运行

点击上方蓝字,关注并星标,和我一起学技术。

大家好,这周我们继续来写一道招聘真题的题解。今天选择的题目来源于字节跳动2019年的春招笔试题,题目来源于牛客网,大家如果感兴趣可以去牛客网的题库当中实际参与。

我选的这一套题一共7题,这是其中的第三题,算是难度中规中矩的一题,比较考验基本功,很适合用来做笔试题。老规矩,我们废话不多说,先来看题意。

题意

小包最近迷上了一款叫做雀魂的麻将游戏,但是这个游戏规则太复杂,小包玩了几个月了还是输多赢少。

于是生气的小包根据游戏简化了一下规则发明了一种新的麻将,只留下一种花色,并且去除了一些特殊和牌方式(例如七对子等),具体的规则如下:

  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张牌中,再取一张牌,取到哪几种数字牌可以和牌。

输入描述:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
输入只有一行,包含13个数字,用空格分隔,每个数字在1~9之间,数据保证同种数字最多出现4次。
输出描述:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
输出同样是一行,包含1个或以上的数字。代表他再取到哪些牌可以和牌。若满足条件的有多种牌,请按从小到大的顺序输出。若没有满足条件的牌,请输出一个数字0

样例

输入例子1:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
1 1 1 2 2 2 5 5 5 6 6 6 9
输出例子1:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
9
例子说明1:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
可以组成1,2,6,74个刻子和9的雀头
输入例子2:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
1 1 1 1 2 2 3 3 5 6 7 8 9
输出例子2:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
4 7
例子说明2:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
1做雀头,组123,123,567456,789的四个顺子
输入例子3:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
1 1 1 2 2 2 3 3 3 5 7 7 9
输出例子3:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
0
例子说明3:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
来任何牌都无法和牌

题解

如果会打麻将的小伙伴看到这题应该很熟悉,这不就是麻将3x+2的胡牌规则么?

所谓的3x即是可以组在一起的三张牌,也就是题目中说的顺子和刻子。而+2,加的是两张一样的牌,对应题目当中的雀头。这题要做的就是给定现在摸到的牌型,然后给出听胡的牌。

我们很容易可以想到我们可以用一个长度为10的数组来存储现在已经摸到的牌,比如我们令这个数组叫做cards。cards[3]=2就说明我们有两张3,cards[6]=3就说明我们有3张6。这样把牌和对应的数量关联起来,我们就可以很方便地判断顺子和刻子的情况了。

存储搞定了之后,我们接下来要搞定的是胡牌以及听牌。其中听牌比较简单,我们只需要额外增加一张牌判断是否胡牌就可以了。比如说我们多摸了一张3之后,判断可以胡牌了,那么说明当前我们听的牌当中就有3。由于一共只有10张牌,我们只需要枚举一下可以听的牌即可。这里有一个小trick不小心很容易忽略,因为麻将当中一种牌最多只有4张,所以我们只需要考虑数量小于4的牌

胡牌的判断也很直观,可以分为雀头和刻子顺子两个部分。雀头好办,我们只需要枚举数量大于2的牌让它们成为雀头,判断剩下的牌能否全部组成顺子或者是刻子即可。全题唯一的难点就在这个组合的判断,虽然去掉雀头之后只有12张牌,也就是4个顺子或者是刻子,但由于顺子和刻子之间可以各种组合,尝试枚举是非常困难的,也是几乎不可能实现的。

如果看过我之前的文章,应该能反应过来,这里其实是一个经典的搜索问题。我们要枚举一下解是否成立,那么最好的办法就是尝试着把当前12张牌拆分成一个一个的顺子和刻子。如果能全部拆分完,那么就说明可以胡牌,否则则不行。搜索的情况只有两种,一种是组成顺子一种是组成刻子,倒是不复杂,但这里的代码却不好写。因为这是一个返回类型是bool型的深度优先搜索,对于新手而言可能相对比较陌生。

关于这个问题没有什么太好的办法,只有加大训练量以及多思考。一定要从递归的原理上去理解,只是把代码记下来似懂非懂是不行的,如果面试白板编程的时候碰到,肯定是会露馅的。

只要能反应过来这是一个搜索问题,并且对相关的代码还熟练的话,这题还是挺简单的,没有太多的trick和弯弯绕,数据也比较弱不用担心超时的问题。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <vector>
#include <cmath>
#include <cstdlib>
#include <string>
#include <map>
#include <set>
#include <algorithm>
#include "time.h"
#include <functional>
#define rep(i,a,b) for (int i=a;i<b;i++)
#define Rep(i,a,b) for (int i=a;i>=b;i--)
#define foreach(e,x) for (__typeof(x.begin()) e=x.begin();e!=x.end();e++)
#define mid ((l+r)>>1)
#define lson (k<<1)
#define rson (k<<1|1)
#define MEM(a,x) memset(a,x,sizeof a)
#define L ch[r][0]
#define R ch[r][1]
using namespace std;
const int N=1000050;
const long long Mod=1000000007;
int cards[14];

bool examine() {
    bool flag = true;
    // 如果全为0,说明已经拆分完了
    rep(i, 1, 10) if (cards[i]) {
        flag = false;
        break;
    }
    if (flag) return true;
    rep(i, 1, 10) {
        // 判断刻子
        if (cards[i] > 2) {
            cards[i] -= 3;
            flag |= examine();
            cards[i] += 3;
        }
        // 判断顺子
        if (i < 8 && cards[i] && cards[i+1] && cards[i+2]) {
            cards[i] -= 1;
            cards[i+1] -= 1;
            cards[i+2] -= 1;
            flag |= examine();
            cards[i]++;
            cards[i+1]++;
            cards[i+2]++;
        }
    }
    return flag;
}


int main() {
    rep(i, 0, 13) {
        int n;
        scanf("%d", &n);
        cards[n] ++;
    }
    vector<int> ret;
    // 枚举听牌
    rep(i, 1, 10) {
        if (cards[i] == 4) continue;
        cards[i] ++;
        // 枚举雀头
        rep(j, 1, 10) {
            if (cards[j] > 1) {
                cards[j] -= 2;
                // 递归
                if (examine()) {
                    ret.push_back(i);
                    cards[j] += 2;
                    break;
                }
                cards[j] += 2;
            }
        }
        cards[i] --;
    }
    if (ret.size() == 0) {
        puts("0");
        return 0;
    }
    sort(ret.begin(), ret.end());
    rep(i, 0, ret.size() - 1) {
        printf("%d ", ret[i]);
    }
    printf("%d\n", ret[ret.size() - 1]);
    return 0;
}

为什么说这题很好呢,因为它考察的算法比较直白,也比较基础,即使没有参加过算法竞赛的同学也能做。但它又不是那么简单,可能很多同学能反应过来它是搜索问题,但是想要把这个dfs函数写正确,并且能在短时间内debug完通过还不是那么容易的。刚入门的新手估计能跑通就要半天,能够快速做出来并且通过一定是基础不错、代码功底比较扎实的同学。

好的问题并不一定就难,更重要的是区分度,可以把候选人的能力区分出来。大家如果准备面试做题练习的话,不妨从这个角度入手思考思考。

好了,今天的文章就到这里,衷心祝愿大家每天都有所收获。如果还喜欢今天的内容的话,请来一个三连支持吧~(点赞、在看、转发)

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-12-20,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Coder梁 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
科学瞎想系列之二十六 陀螺仪
陀螺是老师小时候最喜欢的玩具之一,一个锥形的东东用小皮鞭一抽,就能大头朝上小头朝下高速地旋转起来,冬天在冰面上玩这个玩意其乐无穷。那个时候老师就想为什么它一转起来就能立住不倒,而且转得越快立得就越直,一旦转慢了就开始摇头晃脑,直到最后倒下。这是为什么呢?这个疑问直到老师上了大学,学了普通物理才被解开。前些天,一个航天系统的粉丝宝宝让我瞎想一下陀螺的故事,那就这这里给宝宝们说说这个事。由于这里没法画图,而陀螺的故事又是发生在一个立体空间的故事,要想说清楚,将极大地考验老师的文字表达能力,同时也极大
标准答案
2018/04/18
1K0
自由漂浮机器人运动学与动力学建模:space robot工具箱
根据冗余空间机器人的拓扑形式,建立其运动学方程,进而可以得到各个部分之间的位置关系、速度关系以及加速度关系。基座的运动将会引起机械臂末端的位置和姿态的变化,由于空间机器人在自由漂浮状态下的动量守恒,任意时刻基座的动量和机械臂的动量可以表示成一阶微分形式,进而,基座的运动关系可以表示为机械臂的各个关节角度的表达式。
ZC_Robot机器人技术
2020/11/14
5K11
自由漂浮机器人运动学与动力学建模:space robot工具箱
【Unity3d游戏开发】Unity3D中常用的物理学公式
  马三最近在一直负责Unity中的物理引擎这一块,众所周知,Unity内置了NVIDIA公司PhysX物理引擎。然而,马三一直觉得只会使用引擎而不去了解原理的程序猿不是一位老司机。所以对一些常用的物理学公式我们还是要了解一下的。下面就是Unity开发中常用的一些物理学公式。
马三小伙儿
2018/09/12
2.8K0
【Unity3d游戏开发】Unity3D中常用的物理学公式
无人直升机之旋翼篇
直升机作为20世纪航空技术极具特色的创造之一,极大的拓展了飞行器的应用范围。直升机是典型的军民两用产品,在军用方面,无人直升机既能执行各种非杀伤性任务,又能执行各种软硬杀伤性任务,包括侦察、监视、目标截获、诱饵、攻击、通信中继等。在民用方面,无人直升机在大气监测、交通监控、资源勘探、电力线路检测、森林防火等方面具有广泛的应用前景。
用户7053485
2020/06/19
2.9K0
从零开始读懂物理学:探索自然的奥秘
物理学是一门研究物质、能量和它们之间相互作用的科学学科。它涵盖了广泛的领域,包括力学、热学、电磁学、光学、声学等。每个分支都探索不同方面的物理现象和规律。
海拥
2023/07/05
4370
【一统江湖的大前端(8)】matter.js 经典物理
在前端开发领域,物理引擎是一个相对小众的话题,它通常都是作为游戏开发引擎的附属工具而出现的,独立的功能演示作品常常给人好玩但是无处可用的感觉。仿真就是在计算机的虚拟世界中模拟物体在真实世界的表现(动力学仿真最为常见)。仿真能让画面中物体的运动表现更符合玩家对现实世界的认知,比如在《愤怒的小鸟》游戏中被弹弓发射出去小鸟或是因为被撞击而坍塌的物体堆,还有在《割绳子》小游戏中割断绳子后物体所发生的单摆或是坠落运动,都和现实世界的表现近乎相同,游戏体验通常也会更好。
大史不说话
2020/03/12
3.5K1
基于空间矢量的机器人动力学建模与对比分析
普通的矢量属于3D矢量,即每个3D矢量是由空间的三个标量表示,举例来说,空间的某个位置矢量是由三个XYZ轴的标量值得到,空间的力矢量是力在XYZ轴的标量值合成,力矩也是三个标量合成。而在6D 空间矢量则是分为运动学量以及动力学量,具体为
ZC_Robot机器人技术
2020/09/19
3.2K9
基于空间矢量的机器人动力学建模与对比分析
柔性机器人动力学方程
机械臂的动力学在机械臂的控制中具有十分重要的意义,建立机械臂的动力学模型,是描述控制系统的依据,也是设计控制器的前提。机械臂动力学建模的常用方法是拉格朗日法和牛顿-欧拉法。采用牛顿-欧拉法建立机械臂动力学模型时,要计算每个部分加速度,然后消去内作用力,牛顿-欧拉法是解决动力学问题的力平衡方法。但是,当机械臂变得复杂,此方法的计算也将变得复杂。拉格朗日法依据的是能量平衡原理,不需要对内作用力进行求解。对于多自由度复杂度高的机械臂,拉格朗日法比牛顿-欧拉法的求解更适用。
ZC_Robot机器人技术
2021/03/07
4.8K6
柔性机器人动力学方程
用Mathematica中的阿基米德螺线和复杂代数分析太空中杂耍的模式
宇航学报182:46-57. https://doi.org/10.1016/j.actaastro.2021.02.001
WolframChina
2021/10/22
7270
机器人动力学建模:机械臂动力学
多体系统动力学形成了多种建模和分析的方法, 早期的动力学研究主要包括 Newton-Euler 矢量力学方法和基于 Lagrange 方程的分析力学方法。 这种方法对于解决自由度较少的简单刚体系统, 其方程数目比较少, 计算量也比较小, 比较容易, 但是, 对于复杂的刚体系统, 随着自由度的增加, 方程数目 会急剧增加, 计算量增大。 随着时代的发展, 计算机技术得到了突飞猛进的进步, 虽然可以利用计算机编程求解出动力学方程组, 但是, 对于求解下一时刻的关节角速度需要合适的数值积分方法, 而且需要编写程序, 虽然这种方法可以求解出方程的解, 但是, 由于这种编程方法不具有通用性, 针对每个具体问题, 都需要编程求解, 效率比较低, 因此, 如果能在动力学建模的同时就考虑其计算问题, 并且在建模过程中考虑其建模和求解的通用性, 就能较好的解决此问题。
ZC_Robot机器人技术
2020/10/15
8.7K1
机器人动力学建模:机械臂动力学
固定基座机器人与漂浮基座动力学建模异同点
本章将重点介绍空间矢量描述的空间机械臂动力学建模,其克服了传统的动力学建模其计算量较大,计算效率低的问题。且结合空间固定基座机械臂的正向动力学建模方法,分析动力学建模的效率、计算量以及稳定性问题。动力学建模的基本原理很多,实现方法也很多,动力学量的表示方法也不尽相同,因此针对不同的建模对象,不同的动力学建模任务,需要选择不同的建模方法。本章结合动力学建模方法分析了固定基座机器人动力学建模与漂浮基座机器人动力学建模的异同点。
ZC_Robot机器人技术
2020/10/18
4.4K4
固定基座机器人与漂浮基座动力学建模异同点
柔性机械臂:动力学建模具体方法
建立柔性机械臂动力学方程主要利用Newton-Euler和Lagrange方程这两个最具代表性的方程,另外比较常用的还有Kane方法等。为了建立动力学模型和控制的方便,柔性关节一般简化为弹簧。当连杆存在柔性时,常采用假设模态法、有限元法、有限段法等方法描述相应臂杆的柔性变形,然后再根据需要进行截断。柔性臂杆的变形常常简化为Euler-Bernulli梁来处理,即考虑到机械臂连杆的长度总比其截面尺寸大得多,运行过程中所产生的轴向变形和剪切变形相对于挠曲变形而言非常小,柔性臂杆只考虑挠曲变形,忽略轴向变形和剪切变形。因而从动力学角度看,每根柔性连杆都可视为一段梁。
ZC_Robot机器人技术
2020/10/03
4.7K22
柔性机械臂:动力学建模具体方法
武汉理工大学1997年机械原理考研真题
三、基本参数为标准值的渐开线齿轮,基圆和齿根圆那个大?两圆相等时齿轮的齿数应该是多少?实际上基圆和齿根圆能不能重合?(
用户9628320
2022/11/23
3370
武汉理工大学1997年机械原理考研真题
魔幻!奥运女子体操团体赛多队失误,从惯性矩角度分析一下?
先是有「美国体操女王」之称的西蒙·拜尔斯(Simone Biles)跳马失误后因病退赛。
新智元
2021/07/29
3510
基于matlab的机械臂仿真_移动机器人matlab运动学仿真
目的 本文手把手教你在 Mathematica 科学计算软件中搭建机器人的仿真环境,具体包括以下内容:    1 导入机械臂的三维模型    2 正\逆运动学仿真    3 碰撞检测    4 轨迹规划    5 正\逆动力学仿真    6 运动控制 文中的所有代码和模型文件都在此处:https://github.com/robinvista/Mathematica 。使用的软件版本是 Mathematica 11.1,较早的版本可能缺少某些函数,所以最好使用最新版。交流网站是www.robotattractor.com。进入正文之前不妨先看几个例子:
全栈程序员站长
2022/11/01
5K0
基于matlab的机械臂仿真_移动机器人matlab运动学仿真
理论力学回顾
最近搞毕业设计遇到了一些理论力学的问题,发现自己忘记的好快,所以来回顾一下。理论力学是各种力学的基础,讨论物体不失效,不变形情况下运动和力的关系
用户6948990
2025/04/03
420
理论力学回顾
机械臂运动学整理
空间中的刚体,要描述其状态一般需要6个参数,3个平动参数,3个转动参数,分别对应着世界直角坐标系的三个轴X,Y,Z。
算法之名
2023/10/16
3640
机械臂运动学整理
常用坐标系简介(正在完善~)
引入正则坐标主要还是为了处理约束问题的,也就是用直角坐标描述问题可能会有多余的自由度,比如一个粒子在一个圆环上运动,用直角坐标需要两个坐标,实际上只有角度一个坐标起作用。
全栈程序员站长
2021/04/07
7230
牛顿运动定律的谜团(四)——牛顿定律的数学模型
光说不练假把式,今天我们尝试用数学模型的框架,用现代数学语言来完整描述一番牛顿运动定律从物理实际到数学结构到底是什么,好对他当时到底构建了一个怎样的物理世界盖棺定论。
magic2728
2024/01/10
2750
牛顿运动定律的谜团(四)——牛顿定律的数学模型
自由漂浮机器人
漂浮基座机器人存在动力学耦合,机械臂的关节运动将会引起基座位置和姿态的改变。根据基座的控制方式,可以将漂浮基座机器人分为四种模式:
ZC_Robot机器人技术
2020/08/26
4K4
自由漂浮机器人
推荐阅读
相关推荐
科学瞎想系列之二十六 陀螺仪
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档