每天,农夫约翰的 头奶牛都会穿过农场中间的马路。
考虑约翰的农场在二维平面的地图,马路沿水平方向延伸,马路的一侧由直线 描述,另一侧由直线
描述。
奶牛 i 从马路一侧的位置 沿直线过马路到达另一侧的位置
。
所有 互不相同,所有
互不相同。
尽管他的奶牛们行动敏捷,他还是担心行动路径交叉的两头奶牛在过马路时发生碰撞。
约翰认为,如果一头奶牛的行动路径没有跟其他任何奶牛的行动路径相交,则该奶牛是安全的。
请帮助约翰计算安全奶牛的数量。
输入格式
第一行包含整数 。
接下来 行,每行包含两个整数
,用来描述一头牛的行动路径。
输出格式
输出安全奶牛的数量。
数据范围
输入样例:
4
-3 4
7 8
10 16
3 9
输出样例:
2
样例解释
第一头牛和第三头牛的行动路线不与其他奶牛的路线相交。
第二头牛和第四头牛的行动路线相交。
解题思路
- 以 a 进行排序(升序)
- 此时,如果
这条线没有与其他线相交等价于
并且
- 所以可以用前缀最大值和后缀最小值实现上述操作
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;
}