Codeforces-961D 发表于 2018-04-12 | 分类于 ACM | 浏览 次 题意给出一些点,判断这些点能否都在小于等于两条直线上 思路首先找出三个不在一条直线上的点,可以得到三条直线。依次枚举每条直线可解。 代码123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102#include <cstdio>#include "stack"#include "list"#include <cstring>#include <algorithm>#include "iostream"#include <cmath>#include <vector>#include "set"#include "queue"using namespace std;#define FOP freopen("input.txt","r",stdin)#define R index*2+1#define Met(x,y) memset(x,y,sizeof x)#define L index*2typedef long long ll;const ll MAXN =3e5+100;const ll INF = 1e18;const ll MOD = 1e9+7;struct Point{ ll x,y; bool exist; void read() { scanf("%lld%lld",&x,&y); } Point(double x_=0,double y_=0) { x=x_,y=y_; } Point operator -(const Point& rhs) { return Point(x-rhs.x,y-rhs.y); }};struct Line{ ll A,B,C; Line(Point a,Point b) { A=b.y-a.y; B=a.x-b.x; C=b.x*a.y-a.x*b.y; } Line(){}};Point p[MAXN];bool PointOnLine(Point a,Line b){ return b.A*a.x+b.B*a.y+b.C==0;}int main(int argc, char const *argv[]) { // freopen("input.txt","r",stdin); ll n; cin>>n; for(int i=0;i<n;++i) p[i].read(); if(n<=4) { puts("YES"); return 0; } Line l[2]; ll pp[3]; pp[0]=0; pp[1]=1; Line tem(p[0],p[1]); bool flag=1; for(int i=2;i<n;++i) if (!PointOnLine(p[i],tem)) { pp[2]=i; flag=0; } if (flag) { puts("YES"); return 0; } for(int i=0;i<3;++i) { l[0]=Line(p[pp[i]],p[pp[(i+1)%3]]); bool yes=1,al=0; for(int j=0;j<n;++j) if (al) { if(!PointOnLine(p[j],l[0]) && !PointOnLine(p[j],l[1])) { yes=0; break; } } else { if(i==2 && j==1) i=i; if(PointOnLine(p[j],l[0]) || j==pp[(i+2)%3]) continue; al=1; l[1]=Line(p[j],p[pp[(i+2)%3]]); } if (yes) { puts("YES"); return 0; } } puts("NO"); return 0;}