POJ 3130 How I Mathematician Wonder What You Are!(半平面交求多边形的核)

题目链接

题意 : 给你一个多边形,问你该多边形中是否存在一个点使得该点与该多边形任意一点的连线都在多边形之内。

思路 : 与3335一样,不过要注意方向变化一下。

 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <iostream>
 4 #include <math.h>
 5
 6 using namespace std ;
 7
 8 struct node
 9 {
10     double x;
11     double y ;
12 } p[110],temp[110],newp[110];//p是最开始的多边形的每个点,temp是中间过程中临时存的多边形的每个点,newp是切割后的多边形的每个点
13 int n,newn ;//原来的点数,切割后的点数
14 double a,b,c ;//直线方程的三个系数
15
16 void getline(node x,node y)//求x与y两点确定的直线方程ax+by+c=0
17 {
18     a = y.y-x.y ;
19     b = x.x-y.x ;
20     c = y.x*x.y - y.y*x.x ;
21 }
22 node intersect(node x,node y)//求x与y点确定的直线与ax+by+c=0这条直线的交点
23 {
24     double u = fabs(a*x.x+b*x.y+c) ;
25     double v = fabs(a*y.x+b*y.y+c) ;
26     node t ;
27     t.x = (x.x*v+y.x*u)/(u+v) ;//y.y-x.y=u+v;y.y-t.y=v;y.y-x.y=u;
28     t.y = (x.y*v+y.y*u)/(u+v) ;
29     return t ;
30 }
31 void cut()
32 {
33     int cutn = 0 ;
34     for(int i = 1 ; i <= newn ; i++)
35     {
36         if(a*newp[i].x+b*newp[i].y+c >= 0)//所有的点都大于0,说明所有的点都在这条直线的另一边,所以不用切
37             temp[ ++cutn] = newp[i] ;
38         else
39         {
40             if(a*newp[i-1].x+b*newp[i-1].y+c > 0)
41                 temp[++cutn ] = intersect(newp[i-1],newp[i]) ;//把新交点加入
42             if(a*newp[i+1].x+b*newp[i+1].y+c > 0)
43                 temp[ ++cutn] = intersect(newp[i+1],newp[i]) ;
44         }
45     }
46     for(int i = 1 ; i <= cutn ; i++)
47         newp[i] = temp[i] ;
48     newp[cutn+1] = temp[1] ;//能够找出所有点的前驱和后继
49     newp[0] = temp[cutn] ;
50     newn = cutn ;
51 }
52
53 void solve()
54 {
55     for(int i = 1 ; i <= n ; i++)
56     {
57         newp[i] = p[i] ;
58     }
59     p[n+1] = p[1] ;
60     newp[n+1] = newp[1] ;
61     newp[0] = newp[n] ;
62     newn = n ;
63     for(int i = 1 ; i <= n ; i++)
64     {
65         getline(p[i],p[i+1]) ;//从头开始顺序遍历两个相邻点。
66         cut() ;
67     }
68 }
69 void guizhenghua()
70 {
71     for(int i = 1 ; i < (n+1)/2 ; i++)//规整化方向,顺时针变逆时针,逆时针变顺时针。
72         swap(p[i],p[n-i]) ;
73 }
74 int main()
75 {
76     while(scanf("%d",&n)!=EOF && n)
77     {
78         for(int i = 1 ; i <= n ; i++)
79             scanf("%lf %lf",&p[i].x,&p[i].y) ;
80             guizhenghua() ;
81             p[n+1] = p[1] ;
82         solve() ;
83         if(newn == 0) puts("0") ;
84         else puts("1") ;
85     }
86     return 0;
87 }

时间: 2024-08-07 07:07:01

POJ 3130 How I Mathematician Wonder What You Are!(半平面交求多边形的核)的相关文章

POJ 3130 How I Mathematician Wonder What You Are! 半平面交求多边形内核是否存在

题目大意:定义一种多边形,叫做星形多边形.这种多边形就是有内核的多边形.给出一些多边形,问是否是星形多边形. 思路:利用半平面交求解.PS:我的第一个多边形内核的代码不对..一定要看这个,这个是我看了学长的代码之后才发现之前的代码的问题的,这个也不用微调,是准确值,总值千万不要去看前面的那篇!!!! 由于内核中的所有点到图形上所有点的连线之间不能有边阻挡,所以为了满足任意一条边,需要满足内核的点必须在这条边所在直线的左边,所以将所有组成多边形的边所在的直线进行半平面交即可.由于一个多边形的内核也

POJ 3335 半平面交求多边形的核

Rotating Scoreboard Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 4899   Accepted: 1946 Description This year, ACM/ICPC World finals will be held in a hall in form of a simple polygon. The coaches and spectators are seated along the ed

POJ 1474 Video Surveillance 半平面交求多边形是否有核

裸的半平面交求多边形是否有核. 多边形的核: 在多边形核上的点可以看到多边形的所有顶点,凸多边形的核显然就是多边形本身. 多边形的核是一个凸包,对多边形的所有边都做向着多边形的半平面交在判断一下是否构成凸包就可以了 一样的题目还有POJ3335 Video Surveillance Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 3438   Accepted: 1523 Description A friend of y

POJ 3335 Rotating Scoreboard 半平面交求多边形内核

题目大意:多边形求内核模板题 思路:半平面交,我用的是O(nlogn)的半平面交,但是有一个问题,就是当多边形内核是一个点的时候,半平面交所得到的答案是空集合,但是输出应该是yes,实在没有什么好的解决方法,最后只能把所有直线向右移动,然后在求内核.但是这样做eps的不同取值有的时候能A有的时候不能A.有没有什么好的解决方法啊!!!求解答啊!!! CODE: #include <cmath> #include <cstdio> #include <cstring> #i

POJ 1474 Video Surveillance 半平面交求多边形内核存在性

题目大意:一个楼有很多层,每一层是一个多多边形,问每一层是否有点能够看到这一层的全貌. 思路:半平面交解多边形内核存在性,裸题.题中怎么没写数据范围?..让我还re几次.. CODE: #include <cmath> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define MAX 3010 #define EPS 1e-8 #de

poj 3130 How I Mathematician Wonder What You Are!

How I Mathematician Wonder What You Are! Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 3568   Accepted: 1906 Description After counting so many stars in the sky in his childhood, Isaac, now an astronomer and a mathematician uses a big

poj 3335 /poj 3130/ poj 1474 半平面交 判断核是否存在 / poj1279 半平面交 求核的面积

1 /*************** 2 poj 3335 点序顺时针 3 ***************/ 4 #include <iostream> 5 #include <cmath> 6 #include <algorithm> 7 using namespace std; 8 const double eps = 1e-8; 9 const double maxn = 0x7f7f7f7f; 10 int dcmp(double x){ 11 if(fabs(

POJ 2540 半平面交求可行区域面积

Hotter Colder Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 2343   Accepted: 981 Description The children's game Hotter Colder is played as follows. Player A leaves the room while player B hides an object somewhere in the room. Player

poj 1755 Triathlon 半平面交求不等式的 是否为空集-------构造有向直线

题目来源: http://poj.org/problem?id=1755 分析: 设比赛总长度为 1, 其中游泳长度为x, 自行车长度为y, 赛跑长度为 1 - x - y, 则选手 i 打败 选手j (不能并列) 的条件是 x / v[i] + y / u[i] + (1 - x - y) / w[i]  <  x / v[j] + y / u[j] + (1 - x - y) / w[j] 整理为 a*x + b * y + c > 0 (直线向量为 (b , -a))   ,  为逆时针