鏈接:http://poj.org/problem?id=1279
Art Gallery
Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 5337 | Accepted: 2277 |
Description
The art galleries of the new and very futuristic building of the Center for Balkan Cooperation have the form of polygons (not necessarily convex). When a big exhibition is organized, watching over all of the pictures is a big security concern. Your task is that for a given gallery to write a program which finds the surface of the area of the floor, from which each point on the walls of the gallery is visible. On the figure 1. a map of a gallery is given in some co-ordinate system. The area wanted is shaded on the figure 2.
![](http://poj.org/images/1279_1.jpg)
![](http://poj.org/images/1279_1.jpg)
Input
The number of tasks T that your program have to solve will be on the first row of the input file. Input data for each task start with an integer N, 5 <= N <= 1500. Each of the next N rows of the input will contain the co-ordinates of a vertex of the polygon ? two integers that fit in 16-bit integer type, separated by a single space. Following the row with the co-ordinates of the last vertex for the task comes the line with the number of vertices for the next test and so on.
Output
For each test you must write on one line the required surface - a number with exactly two digits after the decimal point (the number should be rounded to the second digit after the decimal point).
Sample Input
1 7 0 0 4 4 4 7 9 7 13 -1 8 -6 4 -4
Sample Output
80.00
Source
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
这道题好坑的,题目根本没题给定的点有序,然后大家就一起照有序的来做了
自己写了个排序的,发现不行,如果默认有序,再去排序,就会得到错误的结
果,主要是极角排序,是根据角度,一点点逆时针移动,会使原多边形改变形
状,进而求出错误的结果。不知道有没有办法去解决这个问题
一下是错误排序代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <stdio.h> 2 #include <math.h> 3 #include <string.h> 4 #include <stdlib.h> 5 #include <iostream> 6 #include <algorithm> 7 8 #define eps 1e-8 9 #define MAXX 1510 10 11 typedef struct point 12 { 13 double x; 14 double y; 15 }point; 16 17 point p[MAXX],s[MAXX]; 18 19 using namespace std; 20 bool dy(double x,double y) 21 { 22 return x>y+eps; 23 } 24 bool xy(double x,double y) 25 { 26 return x<y-eps; 27 } 28 bool dyd(double x,double y) 29 { 30 return x>y-eps; 31 } 32 bool xyd(double x,double y) 33 { 34 return x<y+eps; 35 } 36 bool dd(double x,double y) 37 { 38 return fabs(x-y)<eps; 39 } 40 41 double crossProduct(point a,point b,point c) 42 { 43 return (c.x-a.x)*(b.y-a.y)-(c.y-a.y)*(b.x-a.x); 44 } 45 46 point IntersectPoint(point u1,point u2,point v1,point v2) 47 { 48 point ans=u1; 49 double t = ((u1.x-v1.x)*(v1.y-v2.y)-(u1.y-v1.y)*(v1.x-v2.x))/ 50 ((u1.x-u2.x)*(v1.y-v2.y)-(u1.y-u2.y)*(v1.x-v2.x)); 51 ans.x += (u2.x-u1.x)*t; 52 ans.y += (u2.y-u1.y)*t; 53 return ans; 54 } 55 56 double Area(point p[],int n) 57 { 58 double ans=0.0; 59 for(int i=1; i<n-1; i++) 60 { 61 ans += crossProduct(p[0],p[i],p[i+1]); 62 } 63 return fabs(ans)/2.0; 64 } 65 66 double dist(point a,point b) 67 { 68 return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)); 69 } 70 71 bool cmp(point a,point b) 72 { 73 double tmp=crossProduct(p[0],a,b); 74 if(dd(tmp,0.0)) 75 return dy(dist(p[0],a),dist(p[0],b)); 76 return xy(tmp,0.0); 77 } 78 79 point Getsort(int n) 80 { 81 int tmp=0; 82 for(int i=1; i<n; i++) 83 { 84 if(xy(p[i].x,p[tmp].x) || dd(p[i].x,p[tmp].x)&&xy(p[i].y,p[tmp].y)) 85 { 86 tmp=i; 87 } 88 }// printf("%d^^",tmp); 89 swap(p[0],p[tmp]); 90 sort(p+1,p+n,cmp); 91 } 92 93 void cut(point p[],point s[],int n,int &len) 94 { 95 point tp[MAXX]; 96 p[n]=p[0]; 97 for(int i=0; i<=n; i++) 98 { 99 tp[i]=p[i]; 100 } 101 int cp=n,tc; 102 for(int i=0; i<n; i++) 103 { 104 tc=0; 105 for(int k=0; k<cp; k++) 106 { 107 if(xyd(crossProduct(p[i],p[i+1],tp[k]),0.0)) 108 s[tc++]=tp[k]; 109 if(xy(crossProduct(p[i],p[i+1],tp[k])* 110 crossProduct(p[i],p[i+1],tp[k+1]),0.0)) 111 s[tc++]=IntersectPoint(p[i],p[i+1],tp[k],tp[k+1]); 112 } 113 s[tc]=s[0]; 114 for(int k=0; k<=tc; k++) 115 tp[k]=s[k]; 116 cp=tc; 117 } 118 len=cp; 119 } 120 121 int main() 122 { 123 int t,n,m,i,j; 124 scanf("%d",&t); 125 while(t--) 126 { 127 scanf("%d",&n); 128 for(i=0; i<n; i++) 129 { 130 scanf("%lf%lf",&p[i].x,&p[i].y); 131 } 132 //point tmp=IntersectPoint(p[0],p[1],p[2],p[3]); 133 //printf("%lf %lf ",tmp.x,tmp.y); 134 Getsort(n);//for(i=0; i<n; i++)printf("%lf**%lf* ",p[i].x,p[i].y); 135 int len; 136 cut(p,s,n,len);//for(i=0; i<len; i++)printf("%lf==%lf= ",s[i].x,s[i].y); 137 double area=Area(s,len); 138 printf("%.2lf ",area); 139 } 140 return 0; 141 }
利用面积正负来判断顺or逆,这种代码是以逆时针为主,我的面积顺时针为正,
需要改变方向
这是AC代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <stdio.h> 2 #include <math.h> 3 #include <string.h> 4 #include <stdlib.h> 5 #include <iostream> 6 #include <algorithm> 7 8 #define eps 1e-8 9 #define MAXX 1510 10 11 typedef struct point 12 { 13 double x; 14 double y; 15 }point; 16 17 point p[MAXX],s[MAXX]; 18 19 using namespace std; 20 bool dy(double x,double y) 21 { 22 return x>y+eps; 23 } 24 bool xy(double x,double y) 25 { 26 return x<y-eps; 27 } 28 bool dyd(double x,double y) 29 { 30 return x>y-eps; 31 } 32 bool xyd(double x,double y) 33 { 34 return x<y+eps; 35 } 36 bool dd(double x,double y) 37 { 38 return fabs(x-y)<eps; 39 } 40 41 double crossProduct(point a,point b,point c) 42 { 43 return (c.x-a.x)*(b.y-a.y)-(c.y-a.y)*(b.x-a.x); 44 } 45 46 point IntersectPoint(point u1,point u2,point v1,point v2) 47 { 48 point ans=u1; 49 double t = ((u1.x-v1.x)*(v1.y-v2.y)-(u1.y-v1.y)*(v1.x-v2.x))/ 50 ((u1.x-u2.x)*(v1.y-v2.y)-(u1.y-u2.y)*(v1.x-v2.x)); 51 ans.x += (u2.x-u1.x)*t; 52 ans.y += (u2.y-u1.y)*t; 53 return ans; 54 } 55 56 double Area(point p[],int n) 57 { 58 double ans=0.0; 59 p[n]=p[0]; 60 point tmp; 61 tmp.x=0,tmp.y=0; 62 for(int i=0; i<n; i++) 63 { 64 ans += crossProduct(tmp,p[i],p[i+1]); 65 } 66 return ans/2.0; 67 } 68 69 void changeWise(point p[],int n) 70 { 71 for(int i=0; i<n/2; i++) 72 swap(p[i],p[n-i-1]); 73 } 74 75 double dist(point a,point b) 76 { 77 return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)); 78 } 79 /* 80 bool cmp(point a,point b) 81 { 82 double tmp=crossProduct(p[0],a,b); 83 if(dd(tmp,0.0)) 84 return dy(dist(p[0],a),dist(p[0],b)); 85 return xy(tmp,0.0); 86 } 87 88 point Getsort(int n) 89 { 90 int tmp=0; 91 for(int i=1; i<n; i++) 92 { 93 if(xy(p[i].x,p[tmp].x) || dd(p[i].x,p[tmp].x)&&xy(p[i].y,p[tmp].y)) 94 { 95 tmp=i; 96 } 97 }// printf("%d^^",tmp); 98 swap(p[0],p[tmp]); 99 sort(p+1,p+n,cmp); 100 } 101 */ 102 void cut(point p[],point s[],int n,int &len) 103 { 104 point tp[MAXX]; 105 p[n]=p[0]; 106 for(int i=0; i<=n; i++) 107 { 108 tp[i]=p[i]; 109 } 110 int cp=n,tc; 111 for(int i=0; i<n; i++) 112 { 113 tc=0; 114 for(int k=0; k<cp; k++) 115 { 116 if(xyd(crossProduct(p[i],p[i+1],tp[k]),0.0)) 117 s[tc++]=tp[k]; 118 if(xy(crossProduct(p[i],p[i+1],tp[k])* 119 crossProduct(p[i],p[i+1],tp[k+1]),0.0)) 120 s[tc++]=IntersectPoint(p[i],p[i+1],tp[k],tp[k+1]); 121 } 122 s[tc]=s[0]; 123 for(int k=0; k<=tc; k++) 124 tp[k]=s[k]; 125 cp=tc; 126 } 127 len=cp; 128 } 129 130 int main() 131 { 132 int t,n,m,i,j; 133 scanf("%d",&t); 134 while(t--) 135 { 136 scanf("%d",&n); 137 for(i=0; i<n; i++) 138 { 139 scanf("%lf%lf",&p[i].x,&p[i].y); 140 } 141 double tmp=Area(p,n); 142 if(dy(tmp,0.0)) 143 changeWise(p,n); 144 //point tmp=IntersectPoint(p[0],p[1],p[2],p[3]); 145 //printf("%lf %lf ",tmp.x,tmp.y); 146 //Getsort(n);for(i=0; i<n; i++)printf("%lf**%lf* ",p[i].x,p[i].y); 147 int len; 148 cut(p,s,n,len);//for(i=0; i<len; i++)printf("%lf==%lf= ",s[i].x,s[i].y); 149 double area=Area(s,len); 150 printf("%.2lf ",fabs(area)); 151 } 152 return 0; 153 }