1. 问题描述:
每天,农夫约翰的 N 头奶牛都会穿过农场中间的马路。考虑约翰的农场在二维平面的地图,马路沿水平方向延伸,马路的一侧由直线 y=0 描述,另一侧由直线 y=1 描述。奶牛 i 从马路一侧的位置 (ai,0) 沿直线过马路到达另一侧的位置 (bi,1)。所有 ai 互不相同,所有 bi 互不相同。尽管他的奶牛们行动敏捷,他还是担心行动路径交叉的两头奶牛在过马路时发生碰撞。约翰认为,如果一头奶牛的行动路径没有跟其他任何奶牛的行动路径相交,则该奶牛是安全的。请帮助约翰计算安全奶牛的数量。
输入格式
第一行包含整数 N。接下来 N 行,每行包含两个整数 ai,bi,用来描述一头牛的行动路径。
输出格式
输出安全奶牛的数量。
数据范围
1 ≤ N ≤ 10 ^ 5,
−10 ^ 6 ≤ ai,bi ≤ 10 ^ 6
输入样例:
4
-3 4
7 8
10 16
3 9
输出样例:
2
样例解释
第一头牛和第三头牛的行动路线不与其他奶牛的路线相交。第二头牛和第四头牛的行动路线相交。
来源:https://www.acwing.com/problem/content/description/1980/
2. 思路分析:
我们可以先对每一组(ai,bi)按照ai进行从小到大进行排序,对于任意一条路线如果不与其他任意一条路线相交那么需要满足它前面的最大值小于当前位置的值,后面的最小值大于当前位置的值(ai是从小到大进行排序的所以只需要看bi就行)
3. 代码如下:
class Solution:
def process(self):
n = int(input())
q = list()
for i in range(n):
a, b = map(int, input().split())
q.append((a, b))
# 按照ai进行排序
q.sort(key=lambda x: x[0])
# 插入0这个元素这样下标可以从1开始
q.insert(0, (0, 0))
# 最大是10 ** 6所以声明大一点就可以
INF = 10 ** 8
# 声明长一点的列表
smax, smin = [-INF] * (n + 10), [INF] * (n + 10)
# 从前到后求解最大值和最小值
for i in range(1, n + 1):
smax[i] = max(smax[i - 1], q[i][1])
for i in range(n, 0, -1):
smin[i] = min(smin[i + 1], q[i][1])
res = 0
# 计算答案
for i in range(1, n + 1):
if smax[i - 1] < q[i][1] < smin[i + 1]:
res += 1
return res
if __name__ == '__main__':
print(Solution().process())