1978 奶牛过马路(前缀最值)

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())
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值