题目:
我们有很多区域,每个区域都是从a到b的闭区间,现在我们要从每个区间中挑选至少2个数,那么最少挑选多少个?
输入描述:
第一行是N(N<10000),表示有N个区间,之间可以重复;然后每一行是ai,bi,持续N行,表示现在区间。均小于100000
输出描述:
输出一个数,代表最少选取数量。
示例:
- 输入
-
4 4 7 2 4 0 2 3 6
- 输出
-
4
思路:
贪婪算法。
按照右端点进行从小到大排序,若右端点相同,则按照左端点从小到大排序。这样可以保证如果给出的n个区间存在包含关系,那么被包含的区间一定在包含区间之前。
第一个处理区间选择两个数字,分别是右端点和右端点-1;
r表示上一个处理区间的右端点;
如果当前区间左端点等于l,那么两个区间刚好重复一个数,当前区间可选的一个数为l,故只需再增加当前区间的右端点即可,数量加1,并且更新r为当前区间的右端点;
如果当前区间左端点大于l,那么两个区间不相交,此时再选择当前区间的右端点和右端点-1即可,数量加2,并且更新r为当前区间的右端点;
如果当前区间的左端点小于l,那么两个区间重复大于一个数,则不需要增加,且不更新端点,这样能保证不漏掉应选的数。
代码:
n = int(input())
nums = []
for _ in range(n):
nums.append(list(map(int, input().split())))
nums.sort(key=lambda x: x[1])
temp = []
temp.append(nums[0][1] - 1)
temp.append(nums[0][1])
for i in range(n - 1):
if nums[i + 1][0] == temp[-1]: # 现在处理的区间的左端点等于上一个处理的右端点
temp.append(nums[i + 1][1]) # 添加现在处理的区间的右端点
elif nums[i + 1][0] > temp[-1]: # 现在处理的区间的左端点大于上一个处理的右端点,无相交
temp.append(nums[i + 1][1] - 1) # 添加现在处理的区间的右端点-1
temp.append(nums[i + 1][1]) # 添加现在处理的区间的右端点
print(len(temp))
代码取自牛客网题解~~