算法笔试-编程练习-好题-01

经过之前的练习,我们已经基本熟悉了笔试中的常见题目,接下来我将过滤掉一些特别简单或者特别困难的题目,总结一些会了不难,但没见过可能一时间想不出来的好题。

本文中的好题包括:

1)如何判断两个数是否在一个等差数列中?同余!

2)贪心


P0001. 数组消除

题目内容

给定一个整数数组nums,同时给定一个整数interval。

指定数组nums中的某个元素作为起点,然后以interval 为间隔递增,如果递增的数(包含起点)等于nums中的元素,则数组nums中对应的元素消除,返回消除元素最多的起点元素。如果消除的元素同样多,则返回最小的起点元素。

输入描述

输入格式:

第一行输入整数数组的长度n

第二行输入长度为nn的整数数组nums

第三行输入整数interval

输出描述

起点元素的最小值

样例1

输入

复制代码
6
4 5 7 1 1 2
3

输出

复制代码
1

题目分析:

【题目类型:数学、同余、等差数列】

可以被消除的数字都位于,差为interval的等差数列上,那么如何确定两个数字是否位于该等差数列上呢?同时对于interval取余,余数相等,则位于同一个等差数列上,这就是同余。这个余数就是这个序列的标识。那么我们使用字典实时更新当前序列的中最小值和数字的数量即可。

考察发现数学规律的能力、数据结构的组织能力。

代码:

python 复制代码
n = int(input())
nums = [int(i) for i in input().split()]
ans = {}
interval = int(input())

for i in nums:
    k = i%interval
    if k in ans:
        ans[k]['cnt'] += 1
        if i < ans[k]['re']:
            ans[k]['re'] = i
    else:
        ans[k] = {
            'cnt': 1,
            're': i
        }

cnt = 0
result = 10000000
for k in ans.keys():
    if ans[k]['cnt'] > cnt:
        cnt = ans[k]['cnt']
        result = ans[k]['re']
    elif ans[k]['cnt'] == cnt and result > ans[k]['re']:
        result = ans[k]['re']
print(result)

P0002. 参会

题目内容

有n场编号从0到n−1的博览会将要举办,编号为i的博览会举办时间为[starti,endi],即从第start天到第end天,包含第start​天和第end天。

小塔计划参加这些博览会,每天最多可以参加kk场博览会。请问小塔最多可以参加多少场博览会。需注意,小塔不需要全程参加一场博览会,只需要在某一天参加即可。

输入描述

第一行输入包含两个整数n和k,n表示博览会的数量,k表示每天最多可以参加的博览会的数量。以下n行每行包含两个整数starti​和endi​,表示第i场博览会的举办时间。

输出描述

小塔最多能参加的博览会数量。

样例1

输入

复制代码
3 1
1 2
2 3
1 1

输出

复制代码
3

题目分析

【题目类型:贪心】

一直觉得贪心是比较难的一类题目,遇到一些难题的时候容易出现明确知道用贪心但想不出来如何贪心的问题。比较好的练习方式就是见多识广。

这道题的贪心思想就是,优先参加快结束了的会议,这点想明白了,这题就变成了一道模拟题。更优秀的做法可以结合优先队列,但是下面的代码也能全部AC。

代码:

python 复制代码
# 获取输入
n, k = map(int, input().split())
meetings = {}
for m in range(n):
    s, e = map(int, input().split())
    if s in meetings.keys():
        meetings[s].append(e)
    else:
        meetings[s] = [e]


ans = 0
startDay = sorted(meetings.keys())  # 按顺序遍历每一天
while len(startDay)>0:
    day = startDay.pop(0)

    if len(meetings[day]) <= k:
        ans += len(meetings[day])   # 该天的会议数量不够k,就全用了
    else:
        # 会议数量大于k,则参加end排序前k的会议
        ans += k
        meetings[day] = sorted(meetings[day])
        idx = k
        while idx < len(meetings[day]):   # 并且去掉当天结束的会议
            if meetings[day][idx] > day:
                break
            idx += 1
        
        # 如果仍有会议,则推到下一天
        if idx < len(meetings[day]):
            if day+1 in meetings.keys():
                meetings[day+1] += meetings[day][idx:]
            else:
                meetings[day+1] = meetings[day][idx:]
                startDay.insert(0, day+1)
        
    del meetings[day]
print(ans)
相关推荐
让我们一起加油好吗2 分钟前
【基础算法】枚举(普通枚举、二进制枚举)
开发语言·c++·算法·二进制·枚举·位运算
M1A117 分钟前
Python数据结构操作:全面解析与实践
后端·python
FogLetter20 分钟前
微信红包算法揭秘:从随机性到产品思维的完美结合
算法
扑克中的黑桃A23 分钟前
Python-打印杨辉三角
python
YGGP41 分钟前
吃透 Golang 基础:数据结构之 Map
开发语言·数据结构·golang
BUG收容所所长1 小时前
二分查找的「左右为难」:如何优雅地找到数组中元素的首尾位置
前端·javascript·算法
weixin_419658311 小时前
数据结构之栈
数据结构
图先1 小时前
数据结构第一章
数据结构
程序员三藏1 小时前
如何使用Jmeter进行压力测试?
自动化测试·软件测试·python·测试工具·jmeter·测试用例·压力测试
carpell1 小时前
【语义分割专栏】3:Segnet原理篇
人工智能·python·深度学习·计算机视觉·语义分割