The teacher gave Anton a large geometry homework, but he didn’t do it (as usual) as he participated in a regular round on Codeforces. In the task he was given a set of n lines defined by the equations y = k i·x + b i. It was necessary to determine whether there is at least one point of intersection of two of these lines, that lays strictly inside the strip between x 1 < x 2. In other words, is it true that there are 1 ≤ i < j ≤ n and x’, y’, such that:
- y’ = k i * x’ + b i, that is, point (x’, y’) belongs to the line number i;
- y’ = k j * x’ + b j, that is, point (x’, y’) belongs to the line number j;
- x 1 < x’ < x 2, that is, point (x’, y’) lies inside the strip bounded by
x
1
<
x
2
x 1 < x 2
x1 < x2.
You can’t leave Anton in trouble, can you? Write a program that solves the given task.
Input
The first line of the input contains an integer n (2 ≤ n ≤ 100 000) — the number of lines in the task given to Anton. The second line contains integers x 1 and x2( - 1 000 000 ≤ x 1 < x 2 ≤ 1 000 000) defining the strip inside which you need to find a point of intersection of at least two lines.
The following n lines contain integers ki, b i ( - 1 000 000 ≤ ki, bi ≤ 1 000 000) — the descriptions of the lines. It is guaranteed that all lines are pairwise distinct, that is, for any two i ≠ j it is true that either ki ≠ kj, or bi ≠ bj.
Output
Print “Yes” (without quotes), if there is at least one intersection of two distinct lines, located strictly inside the strip. Otherwise print “No” (without quotes).
Example Output
Input |
---|
4 |
1 2 |
1 2 |
1 0 |
0 1 |
0 2 |
output |
NO |
Input |
---|
2 |
1 3 |
1 0 |
-1 3 |
output |
YES |
Input |
---|
2 |
1 3 |
1 0 |
0 2 |
output |
YES |
Input |
---|
2 |
1 3 |
1 0 |
0 3 |
output |
NO |
Note
In the first sample there are intersections located on the border of the strip, but there are no intersections located strictly inside it.
题意
在给出的的直线中(第三行到最后一行是给出的直线),找出是否存在一个
交点位于X1和X2之间。存在输出“YES”否则输出“NO”。
题解
我们先来分析一下,两条直线相交在X1和X2之间需要满足什么条件,我
画了一个图:
从图上可以看出
y
=
x
y = x
y=x 与
y
=
−
x
+
3
y = -x + 3
y=−x+3 在X1 = 1,X2 = 2之间存在一个
交点……我们来观察一下这两条直线和X1、X2的关系。蓝线与X1的交点在黄线与X1的交点的上方,(决定它们的与X1、X2的交点的高低只有 y 坐标)而与X2的交点,蓝线与X2的交点在黄线的下方。。。这里我们把直线与X1、X2的交点记录下来(只记录 y 坐标就行了)。那么两条直线,分别于 X1,X2 的交点。 一定是一对逆序对。我们可以得到每条直线在 X1,X2 的交点的纵坐标。然后按照与 X1 交点的纵坐标升序排。另外一个比较重要的的是,判断是否有逆序对,只需要判断相邻的就行了。
可以用如下证明(不知道有什么更容易想的办法?)
假设直线i与直线 i+k(k>=2) 相交,直线i与直线 i+j(1=<j<k) 不相交。
那么 li[i].sec < li[i+j].sec, li[i].sec >l i[i+k].sec
所以 li[i+j].sec > li[i].sec > li[i+k].sec
那么直线 i+j 一定与 i+k 相交
当 j=k-1 时,i+j 与 i+k 相邻。
也就是说…如果任意直线i与j相交…我们总可以转化成一对相邻的直线相交。
因此只判断相邻直线的相交就可以。
AC代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 100005;
ll n,x1,x2;
pair<ll,ll> li[N];
int main()
{
scanf("%lld",&n);
scanf("%lld %lld",&x1,&x2);
for(int i=0;i<n;i++)
{
ll k,b;
scanf("%lld %lld",&k,&b);
li[i] = make_pair(k*x1+b,k*x2+b);
}
sort(li,li+n);
bool flag = false;
for(int i=1;i<n;i++)
{
if(li[i-1].second > li[i].second) // 因为我们之前是升序排序,按照与X1的交点从小到大
//排序好了,我们只要找到(按照排好的序顺序寻找)有一条线与X2
//的交点大于另外一条的就表示至少有一个交点在X1、X2之间
{
flag = true;
break;
}
}
if(!flag)
printf("NO");
else
printf("YES");
return 0;
}