思路:
假设成立,那么前三个点一定不会全都不在一条直线上,一定有两个点共线。那么就可以从前三个点枚举共线的两个点。将与其共线的点全部标记。再寻找两个没被标记的点,如果找不够两个点,那么这一定是一组解,将与这两个点共线的点标记。如果所有点都被标记,那么这就是一组解。
代码:
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<vector>
#include<queue>
#include<math.h>
using namespace std;
#define MAXN 100005
#define LL long long
int n;
struct node
{
LL x,y;
}p[MAXN];
bool vis[MAXN];
int check(int a,int b)
{
memset(vis,0,sizeof vis);
for(int i=0;i<n;i++)
{
if((p[a].x-p[b].x)*(p[i].y-p[a].y)==(p[a].y-p[b].y)*(p[i].x-p[a].x))
vis[i]=1;
}
int c[2],cnt=0;
for(int i=0;i<n;i++)
{
if(!vis[i])
{
c[cnt++]=i;
}
if(cnt==2) break;
}
if(cnt<2) return 1;
for(int i=0;i<n;i++)
{
if((p[c[0]].x-p[c[1]].x)*(p[i].y-p[c[0]].y)==(p[c[0]].y-p[c[1]].y)*(p[i].x-p[c[0]].x))
vis[i]=1;
}
for(int i=0;i<n;i++)
if(!vis[i]) return 0;
return 1;
}
int main()
{
scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%lld%lld",&p[i].x,&p[i].y);
}
if(n<=4) puts("YES");
else
{
if(check(0,1) || check(0,2) || check(1,2))
puts("YES");
else puts("NO");
}
return 0;
}