字节跳动——手撕代码系列(1)

1、链接:https://www.nowcoder.com/questionTerminal/42852fd7045c442192fa89404ab42e92
来源:牛客网

我叫王大锤,是一家出版社的编辑。我负责校对投稿来的英文稿件,这份工作非常烦人,因为每天都要去修正无数的拼写错误。但是,优秀的人总能在平凡的工作中发现真理。我发现一个发现拼写错误的捷径:

  1. 三个同样的字母连在一起,一定是拼写错误,去掉一个的就好啦:比如 helllo -> hello
  2. 两对一样的字母(AABB型)连在一起,一定是拼写错误,去掉第二对的一个字母就好啦:比如 helloo -> hello
  3. 上面的规则优先“从左到右”匹配,即如果是AABBCC,虽然AABB和BBCC都是错误拼写,应该优先考虑修复AABB,结果为AABCC

我特喵是个天才!我在蓝翔学过挖掘机和程序设计,按照这个原理写了一个自动校对器,工作效率从此起飞。用不了多久,我就会出任CEO,当上董事长,迎娶白富美,走上人生巅峰,想想都有点小激动呢!
……
万万没想到,我被开除了,临走时老板对我说: “做人做事要兢兢业业、勤勤恳恳、本本分分,人要是行,干一行行一行。一行行行行行;要是不行,干一行不行一行,一行不行行行不行。” 我现在整个人红红火火恍恍惚惚的……

请听题:请实现大锤的自动校对程序
输入描述:
第一行包括一个数字N,表示本次用例包括多少个待校验的字符串。
后面跟随N行,每行为一个待校验的字符串。

输出描述:

N行,每行包括一个被修复后的字符串。
在这里插入图片描述
这个题意不是很清楚,不知道是一次输入三行还是一次一行输入三次

n = int(input())
while n>0:
    s = input()
    res = []
    for e in s:
        if len(res) < 2:
            res.append(e)
            continue
        if len(res) >= 2:
            if e == res[-1] and e == res[-2]:
                continue
        if len(res) >= 3:
            if e == res[-1] and res[-2] == res[-3]:
                continue
        res.append(e)
    print(''.join(res))
    n -= 1

2、链接:https://www.nowcoder.com/questionTerminal/c0803540c94848baac03096745b55b9b
来源:牛客网

我叫王大锤,是一名特工。我刚刚接到任务:在字节跳动大街进行埋伏,抓捕恐怖分子孔连顺。和我一起行动的还有另外两名特工,我提议

  1. 我们在字节跳动大街的N个建筑中选定3个埋伏地点。
  2. 为了相互照应,我们决定相距最远的两名特工间的距离不超过D。

我特喵是个天才! 经过精密的计算,我们从X种可行的埋伏方案中选择了一种。这个方案万无一失,颤抖吧,孔连顺!
……
万万没想到,计划还是失败了,孔连顺化妆成小龙女,混在cosplay的队伍中逃出了字节跳动大街。只怪他的伪装太成功了,就是杨过本人来了也发现不了的!

请听题:给定N(可选作为埋伏点的建筑物数)、D(相距最远的两名特工间的距离的最大值)以及可选建筑的坐标,计算在这次行动中,大锤的小队有多少种埋伏选择。
注意:

  1. 两个特工不能埋伏在同一地点
  2. 三个特工是等价的:即同样的位置组合(A, B, C) 只算一种埋伏方法,不能因“特工之间互换位置”而重复使用

输入描述:
第一行包含空格分隔的两个数字 N和D(1 ≤ N ≤ 1000000; 1 ≤ D ≤ 1000000)
第二行包含N个建筑物的的位置,每个位置用一个整数(取值区间为[0, 1000000])表示,从小到大排列(将字节跳动大街看做一条数轴)
输出描述:
一个数字,表示不同埋伏方案的数量。结果可能溢出,请对 99997867 取模
在这里插入图片描述
在这里插入图片描述

# 采用滑动窗口的思想先固定左边移动右边,找到符合条件的右边界,然后使用Cn2,来计算符和条件的个数
n, dist = map(int, input().split())
nums = list(map(int, input().split()))
res = 0
left = 0
right = 2
while left < n-2:# 共有n个点,[0:n-1],因为有三个人,所以左边可以选择的点只有[0:n-3]
    while right < n and nums[right] - nums[left] <= dist: # 找到不符合条件的第一个点
        right += 1
    if right - 1 - left >= 2:# 要保证右边和左边之间要有一个位置用来存放中间的点
        num = right - left - 1  # # 计算两个点之间有几个点
        res += num * (num - 1) // 2 # 从这些点中随便挑出来两个,使用Cn2来计算符合条件的个数
    left += 1  # 移动左边的点

print(res)

3、编写函数get_str,输入参数为一个字符串S,将字符串按1,2,3,4…等递增间隔进行分割,返回分隔后的字符串列表LS,如果分隔位数不足,则停止,示例:S=‘aaghuuu’,则NS=[‘a’,‘ag’,‘huu’];S=‘aa’,则NS=[‘a’]

def get_str(s):
    start = 0
    end = 1
    length = len(s)
    res = []
    dist = 1
    while end < length-1:
        spl = s[start: end]
        res.append(spl)
        start = end
        dist += 1
        end += dist
    return res

s = 'fwoiaksaihfash'
print(get_str(s))

4、链接:https://www.nowcoder.com/questionTerminal/448127caa21e462f9c9755589a8f2416
来源:牛客网

小包最近迷上了一款叫做雀魂的麻将游戏,但是这个游戏规则太复杂,小包玩了几个月了还是输多赢少。
于是生气的小包根据游戏简化了一下规则发明了一种新的麻将,只留下一种花色,并且去除了一些特殊和牌方式(例如七对子等),具体的规则如下:

总共有36张牌,每张牌是1~9。每个数字4张牌。
你手里有其中的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
在这里插入图片描述在这里插入图片描述在这里插入图片描述

def isHu(nums):
    """
    判断是否可以和牌
    :param nums:
    :return:
    """
    if not nums:
        return True
    n = len(nums)
    count0 = nums.count(nums[0])

# 从第一张牌开始,先找出他出现的次数,如果出现大于等于两次,先将这两个重复的作为雀头,
# 再判断后边的时候满足和的条件,再从后边第一张开始判断
# 从n%3是否等于0可以判断出是否已经选过雀头,选过之后就找出其中的顺子和刻子,找出之后去除列表中的顺子和刻子,再进行选择排除
    if n % 3 != 0 and count0 >= 2 and isHu(nums[2:]) == True:
        return True
    if count0 >= 3 and isHu(nums[3:]) == True:
        return True
    if nums[0] + 1 in nums and nums[0] + 2 in nums:
        last_nums = nums.copy()
        last_nums.remove(nums[0])
        last_nums.remove(nums[0] + 1)
        last_nums.remove(nums[0] + 2)
        if isHu(last_nums) == True:
            return True
        return False

def main(nums):
    """
    遍历所有能够和牌的情况
    :param nums:
    :return:
    """
    d = {}
    for i in nums:
        d[i] = d.get(i, 0) + 1  # 用字典存储列表中每张牌出现的次数
    card_list = set(range(1, 10)) - {i for i, v in d.items() if v == 4}
    # 找出nums中已经出现4次的牌,从card_list中删除出现4次的牌,不进行遍历
    res = []
    for i in card_list:
        if isHu(sorted(nums + [i])):
            res.append(i)
    res = ' '.join(str(x) for x in sorted(res)) if res else '0'
    print(res)

s = input()
nums = [int(x) for x in s.split()]
main(nums)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值