Educational Codeforces Round 41 D. Pair Of Lines(961D)

【题意概述】

  给出平面上的10W个点,要求判断这些点能否被两条直线穿过,即一个点至少在一条直线上。

【题解】

  思路很快可以想到。取3个不共线的点,它们形成一个三角形;如果有解,其中的一条直线一定与三角形的一条边重合。于是用这三条边一一进行验证即可。

  第一次交被卡了精度,后来意识到判断三个点是否共线写丑了,其实并不需要求解析式。直接运用相似三角形,移项变成乘法即可。

  

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cstring>
 4 #define LL long long 
 5 #define rg register
 6 #define N 200010
 7 using namespace std;
 8 int n;
 9 bool v[N];
10 struct rec{
11     int x,y;
12 }p[N];
13 inline int read(){
14     int k=0,f=1; char c=getchar();
15     while(c<'0'||c>'9')c=='-'&&(f=-1),c=getchar();
16     while('0'<=c&&c<='9')k=k*10+c-'0',c=getchar();
17     return k*f;
18 }
19 inline bool cmp(rec a,rec b){
20     return a.x==b.x?a.y<b.y:a.x<b.x;
21 }
22 inline bool ok(rec a,rec b){
23     return a.x==b.x&&a.y==b.y;
24 }
25 inline void cal(rec a,rec b,rec &t){
26     if(a.x<b.x) swap(a,b);
27     t.x=a.x-b.x; t.y=a.y-b.y;
28 }
29 inline bool judge(rec p1,rec p2,rec p3){
30     rec t1,t2;
31     cal(p1,p2,t1); cal(p1,p3,t2);
32     return 1ll*t1.x*t2.y-1ll*t1.y*t2.x;
33 }
34 inline bool check(rec p1,rec p2){
35     memset(v,0,sizeof(v));
36     for(rg int i=1;i<=n;i++) if(!judge(p1,p2,p[i])) v[i]=1;
37     rec p3,p4; int cnt=0;
38     for(rg int i=1;i<=n;i++) if(!v[i]){
39         if(!cnt) p3=p[i],cnt++;
40         else p4=p[i],cnt++;
41     }
42     if(cnt<=2) return 1;
43     for(rg int i=1;i<=n;i++) if((!v[i])&&(!judge(p3,p4,p[i]))) v[i]=1;
44     for(rg int i=1;i<=n;i++) if(!v[i]) return 0;
45     return 1;
46 }
47 int main(){
48     n=read();
49     if(n<=3){
50         puts("YES"); return 0;
51     }
52     for(rg int i=1;i<=n;i++) p[i].x=read(),p[i].y=read();
53     sort(p+1,p+1+n,cmp); 
54     n=unique(p+1,p+1+n,ok)-p-1;
55     rec p1=p[1],p2=p[2],p3;
56 //    for(rg int i=1;i<=n;i++) printf("[%d %d]
",p[i].x,p[i].y); puts("");
57     for(rg int i=3;i<=n;i++) if(judge(p1,p2,p[i])){
58         p3=p[i];
59         break; 
60     }
61     if(check(p1,p2)||check(p1,p3)||check(p2,p3)){
62         puts("YES");
63         return 0;
64     }
65     puts("NO");
66     return 0;
67 }
View Code
原文地址:https://www.cnblogs.com/DriverLao/p/8727336.html