标签:模拟,计算几何
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 integersy1, 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;
}