题意:给出n个点的坐标(x,y),问你是否能用2条直线过所有点,可以输出YES,反之NO。
解法:对于这种情况,那我们当n<=4是一定成立的,n>4的时候我们可以任意取3个点,先以3点中的2点画一条直线,把该直线不能过的点存入vector中,在对剩下的所有点进行判断,它们是否都在一条直线上,是的话输出YES,不是则取3点中其他2点重复进行上步骤,直到3种情况都没办法实现,那么可以输出NO了。(其实就是一个散点图中,若能用2条直线覆盖所有点,那么容易取三点中的2点必然与其中一条直线重合,复杂问题简单化)
代码如下:
#include <stdio.h>
#include <string>
#include <cstring>
#include <cmath>
#include <iostream>
#include <algorithm>
#include<map>
#include<vector>
using namespace std;
#define inf 0x3f3f3f3f
#define ll long long
const int maxn = 1e5 + 500;
struct node
{
ll x, y;
}a[maxn];
bool Xmult(node p1, node p2, node p0)
{
return (p1.x - p0.x)*(p2.y - p0.y) - (p2.x - p0.x)*(p1.y - p0.y) == 0 ? true : false;
}
int n;
int vis[maxn];
bool fun()
{
vector<int>q;
int key = 1;
for (int i = 2; i < n; i++)
if (!Xmult(a[0], a[1], a[i]))q.push_back(i);
if (q.size() <= 2)return true;
for (int i = 2; i < q.size(); i++)
if (!Xmult(a[q[0]], a[q[1]], a[q[i]])) {
key = 0; break;
}
if (key)return true;
q.clear(); key = 1;
for (int i = 1; i < n; i++)
if (!Xmult(a[0], a[2], a[i]))q.push_back(i);
if (q.size() <= 2)return true;
for (int i = 2; i < q.size(); i++)
if (!Xmult(a[q[0]], a[q[1]], a[q[i]])) {
key = 0; break;
}
if (key)return true;
q.clear(); key = 1;
for (int i = 0; i < n; i++)
if (!Xmult(a[1], a[2], a[i]))q.push_back(i);
if (q.size() <= 2)return true;
for (int i = 2; i < q.size(); i++)
if (!Xmult(a[q[0]], a[q[1]], a[q[i]])) {
key = 0; break;
}
if (key)return true;
return false;
}
int main()
{
cin >> n;
for (int i = 0; i < n; i++)
scanf("%lld%lld", &a[i].x, &a[i].y);
if (n<=4||fun())
cout << "YES" << endl;
else
cout << "NO" << endl;
return 0;
}