您的位置:首页 > 其它

Codeforces 593B Anton and Lines 【思维】

2015-11-08 12:39 417 查看
B. Anton and Lines

time limit per test
1 second

memory limit per test
256 megabytes

input
standard input

output
standard output

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 = ki·x + bi.
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 x1 < x2.
In other words, is it true that there are1 ≤ i < j ≤ n and x', y',
such that:

y' = ki * x' + bi,
that is, point (x', y') belongs to the line number i;

y' = kj * x' + bj,
that is, point (x', y') belongs to the line number j;

x1 < x' < x2,
that is, point (x', y') lies inside the strip bounded by 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 x1 and x2 ( - 1 000 000 ≤ x1 < x2 ≤ 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, bi ( - 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).

Sample test(s)

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.



题意:给你n条直线,问你在[x1, x2]的开区间里面存不存在至少一个交点。

思路:根据直线的k 和 b求出与x = x1 和 x = x2的交点坐标,分别用lv和rv来记录。

这样只要存在i和j(i != j)满足num[i].lv > num[j].lv && num[i].rv < num[j].rv就可以判定存在交点。

关键在于如何高效的查找。我们可以先按lv升序排列,再按rv升序排列,然后依次比较。

分析比较过程:(数组下标从1-n)首先取一个k = 1,然后遍历i(2 <= i <= n).

我们来比较num[k]和num[i]的lv、rv

(1) 满足上面的判定条件,存在交点;

(2) num[k].lv == num[i].lv,为了最大概率找到交点,我们取rv值较小的代替k向下比较,这样k = i;

(3) num[k].rv > num[i].rv,同(2),k = i;

(4) num[k].rv == num[i].rv,同(2), k = i;

上面的后三种处理可以放在一起。这样查询只需要O(n)的时间复杂度。

注意:lv和rv会超int,一开始还以为自己思路错了。。。

AC代码:

#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <stack>
#include <map>
#include <vector>
#define INF 0x3f3f3f3f
#define eps 1e-8
#define MAXN 100000+10
#define MAXM 50000000
#define Ri(a) scanf("%d", &a)
#define Rl(a) scanf("%lld", &a)
#define Rf(a) scanf("%lf", &a)
#define Rs(a) scanf("%s", a)
#define Pi(a) printf("%d\n", (a))
#define Pf(a) printf("%lf\n", (a))
#define Pl(a) printf("%lld\n", (a))
#define Ps(a) printf("%s\n", (a))
#define W(a) while(a--)
#define CLR(a, b) memset(a, (b), sizeof(a))
#define MOD 1000000007
#define LL long long
#define lson o<<1, l, mid
#define rson o<<1|1, mid+1, r
#define ll o<<1
#define rr o<<1|1
using namespace std;
struct Node{
LL lv, rv;
};
Node num[MAXN];
bool cmp(Node a, Node b)
{
if(a.lv != b.lv)
return a.lv > b.lv;
else
return a.rv > b.rv;
}
int main()
{
int n; Ri(n);
LL x1, x2;
Rl(x1); Rl(x2);
for(int i = 1; i <= n; i++)
{
LL k, b;
Rl(k); Rl(b);
num[i].lv = k * x1 + b;
num[i].rv = k * x2 + b;
}
sort(num+1, num+n+1, cmp);
bool flag = false;
int k = 1;
for(int i = 2; i <= n; i++)
{
if(num[k].lv > num[i].lv && num[k].rv < num[i].rv)
{
flag = true;
break;
}
else
k = i;
}
if(flag)
printf("YES\n");
else
printf("NO\n");
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: