Codeforces849B Tell Your World

标签:模拟,计算几何

Connect the countless points with lines,till we reach the faraway yonder.

There are n points on a coordinateplane, thei-th of which being (i, yi).

Determine whether it's possible to draw twoparallel and non-overlapping lines, such that every point in the set lies on exactlyone of them, and each of them passes through at least one point in the set.

Input

The first line of input contains a positiveintegern (3 ≤ n ≤ 1 000) — the number of points.

The second line containsnspace-separated integers y1, y2, ..., yn ( - 109 ≤ yi ≤ 109) —the vertical coordinates of each point.

Output

Output "Yes" (without quotes) ifit's possible to fulfill the requirements, and "No" otherwise.

You can print each letter in any case(upper or lower).

Example

Input

5
7 5 8 6 9

Output

Yes

Input

5
-1 -2 0 0 -5

Output

No

Input

5
5 4 3 2 1

Output

No

Input

5
1000000000 0 0 0 0

Output

Yes

Note

In the first example, there are fivepoints: (1, 7), (2, 5), (3, 8), (4, 6) and (5, 9). It'spossible to draw a line that passes through points 1, 3, 5, and another one that passes throughpoints 2, 4 and is parallel to the first one.

In the second example, while it's possibleto draw two lines that cover all points, they cannot be made parallel.

In the third example, it's impossible tosatisfy both requirements at the same time.

 

题意:给你一些点的坐标,问能否用两条平行且不重叠的直线完全覆盖这些点

分析:这个B题在比赛的时候貌似卡了不少人,竟然会出计算几何的题目,比赛当时只有暴力的思路,但是O(n^3)肯定会TLE的啊,简直药丸,连B题都搞不了了

第二天早上补题的时候才知道正解思路只用枚举(1,3)(1,2)(2,3)这三种情况,分别算出各情况的斜率和截距,然后带入其他点验证即可。如果不在当前直线的点,再次计算斜率,判断是否完全覆盖和平行就好了

当时的自己那么菜,too young too naïve!

 

参考代码

#include<bits/stdc++.h>
#define eps 1e-7
using namespace std;
inline int read()
{
	int f=1,x=0;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return x*f;
}

int y[1005],n;
bool v[1005];
bool check(double k,int b)
{
	memset(v,0,sizeof(v));
	int cnt=0,pos=0;
	for(int i=1;i<=n;i++)
		if(y[i]-b==k*(i-1))
		{
			v[i]=true;
			cnt++;
		}
		else if(pos==0)pos=i;
//	cout<<pos<<' '<<cnt<<endl;
	if(cnt==n)return false;
	if(cnt==n-1)return true;
	for(int i=pos+1;i<=n;i++)
	    if(!v[i]&&fabs((double)(y[i]-y[pos])/(i-pos)-k)>eps)return false;
	return true;
}

	
int main()
{
	n=read();
	for(int i=1;i<=n;i++)y[i]=read();
    if(check(1.0*(y[2]-y[1]),y[1])|check(0.5*(y[3]-y[1]),y[1])|check(1.0*(y[3]-y[2]),y[2]-(y[3]-y[2])))
        printf("Yes\n");
    else printf("No\n");
    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值