Codeforces - 593B.Anton and Lines 排序+思维

61 篇文章 1 订阅
28 篇文章 0 订阅

1.题目描述:

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 kibi ( - 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.


2.题意概述:

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


3.解题思路:

其实这道也出现在新生赛上面,然后我当时用的叉乘判断直线相交A了,但是cf被卡了,估计是精度问题

根据直线的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)的时间复杂度。


4.AC代码:

#include <algorithm>
#include <stdio.h>
#include <cmath>
#define maxn 2010000
using namespace std;
typedef long long ll;
ll x1, x2, n;
int flag;
struct line
{
	ll ya, yb;
}l[maxn];
int cmp(line a, line b)
{
	if (a.ya != b.ya)
		return a.ya < b.ya;
	return a.yb < b.yb;
}
int main()
{
	while (scanf("%lld", &n) != EOF)
	{
		flag = 0;
		scanf("%lld%lld", &x1, &x2);
		for (ll i = 0; i < n; i++)
		{
			ll k, b;
			scanf("%lld%lld", &k, &b);
			l[i].ya = k * x1 + b;
			l[i].yb = k * x2 + b;
		}
		sort(l, l + n, cmp);
		ll cnt = 0;
		for (ll i = 1; i < n; i++)
		{
			if (l[i].ya > l[cnt].ya && l[i].yb < l[cnt].yb)
			{
				flag = 1;
				break;
			}
			cnt++;
		}
		if (flag)
			puts("YES");
		else
			puts("NO");
	}
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值