【模板】计几 半平面交求多边形内核(n²做法) poj3335

n²做法求多边形内核,由于题目给点是按顺序给的,所以不用再排序。

题目链接:https://vjudge.net/problem/POJ-3335

 1 /*************************************************************************
 2     > File Name: poj3335.cpp
 3 # File Name: poj3335.cpp
 4 # Author : xiaobuxie
 5 # QQ : 760427180
 6 # Email:760427180@qq.com
 7 # Created Time: 2019年09月25日 星期三 18时11分25秒
 8  ************************************************************************/
 9 
10 #include<iostream>
11 #include<cstdio>
12 #include<map>
13 #include<cmath>
14 #include<cstring>
15 #include<set>
16 #include<queue>
17 #include<vector>
18 #include<algorithm>
19 using namespace std;
20 typedef long long ll;
21 #define inf 0x3f3f3f3f
22 #define pq priority_queue<int,vector<int>,greater<int> >
23 ll gcd(ll a,ll b){
24     if(a<b) return gcd(b,a);
25     return b==0?a:gcd(b,a%b);
26 }
27 const int N=106;
28 struct Point{
29     double x,y;
30 }p[N],nowp[N],temp[N];
31 double a,b,c;
32 int n,nown;
33 void getline(Point u,Point v){ // 把u到v这条直线更新为 a b c
34     a=v.y - u.y;
35     b=u.x - v.x;
36     c=v.x * u.y - v.y * u.x;
37 }
38 Point inter(Point u,Point v){  //求uv直线与a b c直线交点
39     double s = a*u.x + b*u.y + c;
40     double t = a*v.x + b*v.y + c;
41     Point res;
42     res.x = (u.x*t + v.x*s)/(s+t);
43     res.y = (u.y*t + v.y*s)/(s+t);
44     return res;
45 }
46 void cut(){   //对在点集内的点进行cut
47     int cutn=0;
48     for(int i=1;i<=nown;++i){
49         if(a*nowp[i].x + b*nowp[i].y + c>=0) temp[++cutn] = nowp[i];
50         else{
51             if(a*nowp[i-1].x + b*nowp[i-1].y + c > 0) temp[++cutn] = inter(nowp[i-1],nowp[i]);
52             if(a*nowp[i+1].x + b*nowp[i+1].y + c > 0) temp[++cutn] = inter(nowp[i+1],nowp[i]);
53         }
54     }
55     for(int i=1;i<=cutn;++i) nowp[i]=temp[i];
56     nowp[cutn+1] = temp[1];
57     nowp[0] = temp[cutn];
58     nown=cutn;
59 }
60 void solve(){
61     for(int i=0;i<=n+1;++i) nowp[i]=p[i];
62     nown=n;
63     for(int i=1;i<=n;++i){
64         getline(p[i],p[i+1]);
65         cut();
66     }
67 }
68 int main(){
69     int T; scanf("%d",&T);
70     while(T--){
71         scanf("%d",&n);
72         for(int i=1;i<=n;++i) scanf("%lf %lf",&p[i].x,&p[i].y);
73         //默认给的是顺时针,若不是要注意一下
74         p[n+1]=p[1]; p[0]=p[n];  //处理两个点的前驱和后驱
75         solve();
76         if(nown) puts("YES");
77         else puts("NO");
78     }
79     return 0;
80 }
View Code

 

posted @ 2019-09-25 19:24  小布鞋  阅读(175)  评论(0编辑  收藏  举报