算法笔试-编程练习-好题-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)
相关推荐
jianglq16 分钟前
C++20 协程:异步编程的新纪元
算法·c++20
wniuniu_1 小时前
动态规划前---选----
算法·动态规划
lzb_kkk2 小时前
【Redis】redis5种数据类型(哈希)
开发语言·redis·算法·缓存·哈希算法
鱼跃鹰飞2 小时前
Leetcode面试经典150题-202.快乐数
算法·leetcode·面试
鱼跃鹰飞2 小时前
Leetcode面试经典150题-82.删除排序链表中的重复元素II
算法·leetcode·面试
易雪寒2 小时前
Maven从入门到精通(三)
java·python·maven
FreakStudio2 小时前
全网最适合入门的面向对象编程教程:49 Python函数方法与接口-函数与方法的区别和lamda匿名函数
python·嵌入式·面向对象·电子diy
Good_tea_h3 小时前
如何实现Java中的多态性
java·开发语言·python
IT毕设梦工厂3 小时前
计算机毕业设计选题推荐-项目评审系统-Java/Python项目实战
java·spring boot·python·django·毕业设计·源码·课程设计
零 度°4 小时前
Qiskit:量子计算的Python工具包
python