每天,农夫约翰的 奶牛过马路(寒假每日一题 9)_算法 头奶牛都会穿过农场中间的马路。

考虑约翰的农场在二维平面的地图,马路沿水平方向延伸,马路的一侧由直线 奶牛过马路(寒假每日一题 9)_i++_02 描述,另一侧由直线 奶牛过马路(寒假每日一题 9)_前缀最大值_03 描述。

奶牛 i 从马路一侧的位置 奶牛过马路(寒假每日一题 9)_后缀最小值_04 沿直线过马路到达另一侧的位置 奶牛过马路(寒假每日一题 9)_算法_05

所有 奶牛过马路(寒假每日一题 9)_i++_06 互不相同,所有 奶牛过马路(寒假每日一题 9)_c++_07 互不相同。

尽管他的奶牛们行动敏捷,他还是担心行动路径交叉的两头奶牛在过马路时发生碰撞。

约翰认为,如果一头奶牛的行动路径没有跟其他任何奶牛的行动路径相交,则该奶牛是安全的。

请帮助约翰计算安全奶牛的数量。

输入格式
第一行包含整数 奶牛过马路(寒假每日一题 9)_算法

接下来 奶牛过马路(寒假每日一题 9)_算法 行,每行包含两个整数 奶牛过马路(寒假每日一题 9)_后缀最小值_10,用来描述一头牛的行动路径。

输出格式
输出安全奶牛的数量。

数据范围
奶牛过马路(寒假每日一题 9)_后缀最小值_11
输入样例:

4
-3 4
7 8
10 16
3 9

输出样例:

2

样例解释
第一头牛和第三头牛的行动路线不与其他奶牛的路线相交。

第二头牛和第四头牛的行动路线相交。


解题思路

  1. 以 a 进行排序(升序)
  2. 此时,如果奶牛过马路(寒假每日一题 9)_算法_12这条线没有与其他线相交等价于奶牛过马路(寒假每日一题 9)_c++_13并且奶牛过马路(寒假每日一题 9)_c++_14
  3. 所以可以用前缀最大值和后缀最小值实现上述操作
#include<iostream>
#include<algorithm>

#define x first
#define y second

using namespace std;

typedef pair<int, int> PII;

const int N = 100010;

PII q[N];
int smax[N], smin[N], INF = 1e8;

int main(){

int n;

scanf("%d", &n);

for(int i = 1; i <= n; i++){

int x, y;
scanf("%d%d", &x, &y);
q[i] = {x, y};
}

sort(q + 1, q + 1 + n);

smax[0] = -INF, smin[n + 1] = INF;
for(int i = 1; i <= n; i++) smax[i] = max(smax[i - 1], q[i].y);
for(int i = n; i >= 1; i--) smin[i] = min(smin[i + 1], q[i].y);

int res = 0;
for(int i = 1; i <= n; i++){

if(q[i].y > smax[i - 1] && q[i].y < smin[i + 1]) res++;
}

printf("%d\n", res);

return 0;
}