poj 3130 How I Mathematician Wonder What You Are! 半平面交判断核存在问题
和poj3335差不多的题目,都是判断多边形核是否存在问题,只不过这里的点是逆时针给出的,所以模板直接用。
1 #include<cmath> 2 #include<algorithm> 3 using namespace std; 4 5 const double MAX =100000000; 6 const double pi =acos(-1.0); 7 const double eps=1e-8; 8 int m,s; 9 struct node 10 { 11 double x,y; //注意类型 12 }tr[110],p[110],q[110]; 13 int sig(double k) 14 { 15 return (k<-eps)?-1:(k>eps); 16 } 17 void interect(node x,node y,double a,double b,double c) 18 { 19 double u=fabs(a*x.x+b*x.y+c); 20 double v=fabs(a*y.x+b*y.y+c); 21 q[++s].x=(x.x*v+y.x*u)/(u+v); 22 q[s].y=(x.y*v+y.y*u)/(u+v); 23 } 24 //利用半平面切割 25 void cut(double a,double b,double c) 26 { 27 s=0; 28 int i; 29 for(i=1;i<=m;i++) //遍历所有顶点是否能观察到该边 30 { 31 if(sig(a*p[i].x+b*p[i].y+c)<=0)//因为线段是逆时针给出的,如果是顺时针就是<=0 32 { 33 q[++s]=p[i]; //若是则存储 34 } 35 else 36 { 37 if(sig(a*p[i-1].x+b*p[i-1].y+c)<0)//顺时针就是<0 38 interect(p[i-1],p[i],a,b,c); 39 if(sig(a*p[i+1].x+b*p[i+1].y+c)<0)//顺时针就是<0 40 interect(p[i+1],p[i],a,b,c); 41 } 42 } 43 //最后的p数组存放半平面的点集合 44 for(i=1;i<=s;i++) 45 p[i]=q[i]; 46 p[s+1]=p[1],p[0]=p[s]; 47 m=s; 48 } 49 50 int main() 51 { 52 int n,i,j,t; 53 while(scanf("%d",&n),n) 54 { 55 for(i=0;i<n;i++) 56 { 57 scanf("%lf%lf",&tr[i].x,&tr[i].y); 58 p[i+1]=tr[i]; //初始化边界 59 } 60 tr[n]=tr[0]; 61 p[n+1]=p[1];p[0]=p[n]; 62 m=n; 63 double a,b,c; 64 for(i=0;i<n;i++) 65 { 66 a=tr[i+1].y-tr[i].y; //计算出相邻两点所在直线ax+by+c=0 67 b=tr[i].x-tr[i+1].x; 68 c=tr[i+1].x*tr[i].y-tr[i].x*tr[i+1].y; 69 cut(a,b,c); 70 } 71 if(!m) puts("0");//这里如果有一个点,或者一条线段都可以,所以判断m是不是等于0就行了,不用判断面积 72 else puts("1"); 73 } 74 return 0; 75 }