算法笔试-编程练习-好题-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)
相关推荐
骑个小蜗牛3 分钟前
Python 标准库:string——字符串操作
python
xiaoshiguang314 分钟前
LeetCode:222.完全二叉树节点的数量
算法·leetcode
爱吃西瓜的小菜鸡15 分钟前
【C语言】判断回文
c语言·学习·算法
别NULL17 分钟前
机试题——疯长的草
数据结构·c++·算法
TT哇21 分钟前
*【每日一题 提高题】[蓝桥杯 2022 国 A] 选素数
java·算法·蓝桥杯
ZSYP-S2 小时前
Day 15:Spring 框架基础
java·开发语言·数据结构·后端·spring
yuanbenshidiaos2 小时前
C++----------函数的调用机制
java·c++·算法
唐叔在学习2 小时前
【唐叔学算法】第21天:超越比较-计数排序、桶排序与基数排序的Java实践及性能剖析
数据结构·算法·排序算法
ALISHENGYA2 小时前
全国青少年信息学奥林匹克竞赛(信奥赛)备考实战之分支结构(switch语句)
数据结构·算法
chengooooooo2 小时前
代码随想录训练营第二十七天| 贪心理论基础 455.分发饼干 376. 摆动序列 53. 最大子序和
算法·leetcode·职场和发展