笔试刷题 | 四道常见题目

前情回顾

笔试刷题 | 积水问题(Python)

笔试刷题 | 快速排序与链表(Python)

笔试刷题 | 贪心算法

笔试刷题 | 回溯法

笔试刷题 | 动态规划-博弈问题

笔试刷题 | 贪心算法与动态规划第二弹 文末附《算法图解》PDF

#! /usr/bin/env python
# -*-coding:utf-8-*-
M = 4
N = 3




class Solution:
"""
世界杯开幕式会在球场C举行,球场C的球迷看台可以容纳M*N个球迷。
在球场售票完成后,现言方想统计此次开幕式一共有多少个球队球迷群体,
最大的球队球迷群体有多少人。
经调研发现,球迷群体在选座时有以下特性:
·同球队的球迷群体会选择相邻座位,不同球队的球迷群体会选择不相邻的座位。
(注解:相邻包括前后相邻、左右相邻、斜对角相邻。)
·给定一个M*N的二维球场,0代表该位置没有坐人,1代表该位置已有球迷,
希望输出球队群体个数P,最大的球队群体人数Q。
"""
    def __init__(self, grid):
        self.grid = grid  # 地图
        self.cnt = 0  # 当前区域人数
        self.dp = []  # 保存所有队伍人数


    def dfs(self, i, j):
        if 0 <= i < M and 0 <= j < N:
            if self.grid[i][j] == 1:
                self.cnt += 1
                self.grid[i][j] = 0  # 经过的点设置成0


                # 八个方向搜索
                self.dfs(i - 1, j)
                self.dfs(i - 1, j - 1)
                self.dfs(i - 1, j + 1)
                self.dfs(i + 1, j)
                self.dfs(i + 1, j - 1)
                self.dfs(i + 1, j + 1)
                self.dfs(i, j + 1)
                self.dfs(i, j - 1)


    def solve(self):
        for i in range(M):
            for j in range(N):
                if self.grid[i][j] == 1:
                    # 每找到一个新区域就清0,因为被搜索过的1都被置0了,所以新区还是1
                    self.cnt = 0
                    self.dfs(i, j)
                    if self.cnt > 0:
                        self.dp.append(self.cnt)


        return len(self.dp), max(self.dp)




def wrong_sen_region_merge():
    """
    病句区间合并
    为了提高文章质量,每一篇文章(假设全部都是英文)
    都会有m名编辑进行审核,每个编辑独立工作,
    会把觉得有问题的句子通过下标记录下来,比如[1,10],
    1表示病句的第一个字符,10表示病句的最后一个字符。
    也就是从1到10这10个字符组成的句子,是有问题的。
    现在需要把多名编辑有问题的句子合并起来,送给总编辑进行最终的审核。
    比如编辑A指出的病句是[1,10],[32,45];B编辑指出的病句是[5,16],
    [78,94],
    那么[1,10]和[5,16]是有交叉的,
    可以合并成[1,16],[32.45],[78.94]
    
    排序 + 贪心算法
    :return:
    """
    arr = [[1, 10], [32, 45], [78, 94], [5, 16], [80, 100], [200, 220], [16, 32]]
    # 每个病句以句头从小到大排序
    arr_sorted = sorted(arr, key=lambda k: k[0])
    print(arr_sorted)
    res = [arr_sorted[0]]
    for item in arr_sorted[1:]:
        if res[-1][1] >= item[0]:
            res[-1][-1] = max(res[-1][-1], item[1])
        else:
            res.append(item)


    s = ''
    for item in res[:-1]:
        s += str(item[0]) + ',' + str(item[1]) + ';'


    s += str(res[-1][0]) + ',' + str(res[-1][1])


    print(s)




def score_sum():
    """
    小a和小b玩一个游戏,有n张卡牌,每张上面有两个正整数x,y。
    取一张牌时,个人积分增加x,团队积分增加y。
    求小a,小b各取若干张牌,使得他们的个人积分相等。


    输入:


    第一行一个整数n。
    接下来n行,每行两个整数x,y,用空格隔开。


    输出:


    一行一个整数
    表示小a的积分和小b的积分相等的时候,团队积分的最大值。


    输入示例:


    4
    3 1
    2 2
    1 4
    1 4


    输出示例:


    10
    :return:
    """
    n = 4
    x = [0, 3, 2, 1, 1]
    y = [0, 1, 2, 4, 4]
    xy = list(zip(x, y))


    xy = sorted(xy, key=lambda t: t[1])
    res = 0
    if sum(x) % 2 == 0:
        # 如果所有x的和为偶数,直接输出
        print(sum(y))
    else:
        for i in range(len(xy)):
            if xy[i][0] % 2 == 1:  # 只取X为偶数的情况
                res = sum([xy[j][1] for j in range(len(xy)) if j != i])
                print(res)
                break
        print(res)




def get_validation_utf():
"""
Leecode原题


一个UTF8字符的长度可能是1到4个字节。其编码规则如下:
对于1字节长的UTF-8字符,第一个bit是0,后面的bit都是它的unicode码;
对于n字节长的UTF-8字符,
前n个bits都是1,第n+1bit是0,接下来的n-1个字节的前两个bits都是10。
"""
    arr = [197, 130, 1]  # 合法
    arr = [235, 140, 4]  # 不合法
    count = 0  # 位数
    flag = True
    for a in arr:
        if count == 0:
            if a >> 3 == 0b11110:
                count = 3


            elif a >> 4 == 0b1110:
                count = 2
            elif a >> 5 == 0b110:
                count = 1
            elif a >> 7 == 0b0:
                count = 0
            else:
                flag = 0
        else:
            if a >> 6 == 0b10:
                count -= 1
            else:
                flag = 0
    print(flag)




if __name__  == '__main__':
    # wrong_sen_region_merge()
    # score_sum()
    get_validation_utf()

关注我的微信公众号~不定期更新相关专业知识~

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值