zoj 1010 (线段相交判断+多边形求面积)

链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=10

Area


Time Limit: 2 Seconds      Memory Limit: 65536 KB      Special Judge


Jerry, a middle school student, addicts himself to mathematical research. Maybe the problems he has thought are really too easy to an expert. But as an amateur, especially as a 15-year-old boy, he had done very well. He is so rolling in thinking the mathematical problem that he is easily to try to solve every problem he met in a mathematical way. One day, he found a piece of paper on the desk. His younger sister, Mary, a four-year-old girl, had drawn some lines. But those lines formed a special kind of concave polygon by accident as Fig. 1 shows.


Fig. 1 The lines his sister had drawn

"Great!" he thought, "The polygon seems so regular. I had just learned how to calculate the area of triangle, rectangle and circle. I‘m sure I can find out how to calculate the area of this figure." And so he did. First of all, he marked the vertexes in the polygon with their coordinates as Fig. 2 shows. And then he found the result--0.75 effortless.


Fig.2 The polygon with the coordinates of vertexes

Of course, he was not satisfied with the solution of such an easy problem. "Mmm, if there‘s a random polygon on the paper, then how can I calculate the area?" he asked himself. Till then, he hadn‘t found out the general rules on calculating the area of a random polygon. He clearly knew that the answer to this question is out of his competence. So he asked you, an erudite expert, to offer him help. The kind behavior would be highly appreciated by him.

Input

The input data consists of several figures. The first line of the input for each figure contains a single integer n, the number of vertexes in the figure. (0 <= n <= 1000).

In the following n lines, each contain a pair of real numbers, which describes the coordinates of the vertexes, (xi, yi). The figure in each test case starts from the first vertex to the second one, then from the second to the third, ???? and so on. At last, it closes from the nth vertex to the first one.

The input ends with an empty figure (n = 0). And this figure not be processed.

Output

As shown below, the output of each figure should contain the figure number and a colon followed by the area of the figure or the string "Impossible".

If the figure is a polygon, compute its area (accurate to two fractional digits). According to the input vertexes, if they cannot form a polygon (that is, one line intersects with another which shouldn‘t be adjoined with it, for example, in a figure with four lines, the first line intersects with the third one), just display "Impossible", indicating the figure can‘t be a polygon. If the amount of the vertexes is not enough to form a closed polygon, the output message should be "Impossible" either.

Print a blank line between each test cases.

Sample Input

5
0 0
0 1
0.5 0.5
1 1
1 0
4
0 0
0 1
1 0
1 1
0

Output for the Sample Input

Figure 1: 0.75

Figure 2: Impossible

-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

一开始看错题意,WA了好多次,要注意与当前线段相邻接的线段不判断

主要就是第一个线段,要跳过与下一条线段的相交性,以及最后一条线段的相交性,其他线段只需要向下跳过一个线段判断相交即可

  1 #include <stdio.h>
  2 #include <string.h>
  3 #include <stdlib.h>
  4 #include <iostream>
  5 #include <algorithm>
  6 #include <math.h>
  7
  8 #define MAXX 1005
  9 #define eps 1e-8
 10 using namespace std;
 11
 12 typedef struct
 13 {
 14     double x;
 15     double y;
 16 }point;
 17
 18 typedef struct
 19 {
 20     point st;
 21     point ed;
 22 }line;
 23
 24 point p[MAXX];
 25 line li[MAXX];
 26
 27 double crossProduct(point a,point b,point c)
 28 {
 29     return (c.x-a.x)*(b.y-a.y)-(c.y-a.y)*(b.x-a.x);
 30 }
 31
 32 double dist(point a,point b)
 33 {
 34     return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
 35 }
 36
 37 bool  xy(double x,double y){ return x < y - eps; }
 38 bool  dy(double x,double y){ return x > y + eps; }
 39 bool xyd(double x,double y){ return x < y + eps; }
 40 bool dyd(double x,double y){ return x > y - eps; }
 41 bool  dd(double x,double y){ return fabs(x-y)<eps; }
 42
 43 bool onSegment(point a,point b,point c)
 44 {
 45     double maxx=max(a.x,b.x);
 46     double maxy=max(a.y,b.y);
 47     double minx=min(a.x,b.x);
 48     double miny=min(a.y,b.y);
 49
 50     if(dd(crossProduct(a,b,c),0.0)&&xyd(c.x,maxx)&&dyd(c.x,minx)
 51        &&xyd(c.y,maxy)&&dyd(c.y,miny))
 52         return true;
 53     return false;
 54 }
 55
 56 bool segIntersect(point p1,point p2,point p3,point p4)
 57 {
 58     double d1=crossProduct(p3,p4,p1);
 59     double d2=crossProduct(p3,p4,p2);
 60     double d3=crossProduct(p1,p2,p3);
 61     double d4=crossProduct(p1,p2,p4);
 62
 63     if(xy(d1*d2,0.0)&&xy(d3*d4,0.0))
 64         return true;
 65     if(dd(d1,0.0)&&onSegment(p3,p4,p1))
 66         return true;
 67     if(dd(d2,0.0)&&onSegment(p3,p4,p2))
 68         return true;
 69     if(dd(d3,0.0)&&onSegment(p1,p2,p3))
 70         return true;
 71     if(dd(d4,0.0)&&onSegment(p1,p2,p4))
 72         return true;
 73     return false;
 74 }
 75
 76 double Area(int n)
 77 {
 78     double ans=0.0;
 79
 80     for(int i=2; i<n; i++)
 81     {
 82         ans+=crossProduct(p[0],p[i-1],p[i]);
 83     }
 84     return fabs(ans)/2.0;
 85 }
 86
 87 int main()
 88 {
 89     int n,m,i,j;
 90     double x,y;
 91     int cas=1;
 92     while(scanf("%d",&n)!=EOF&&n)
 93     {
 94         for(i=0; i<n; i++)
 95         {
 96             scanf("%lf%lf",&p[i].x,&p[i].y);
 97         }
 98
 99         for(i=0; i<n-1; i++)
100         {
101             li[i].st.x=p[i].x;
102             li[i].st.y=p[i].y;
103             li[i].ed.x=p[i+1].x;
104             li[i].ed.y=p[i+1].y;
105         }
106         li[n-1].st.x=p[n-1].x;
107         li[n-1].st.y=p[n-1].y;
108         li[n-1].ed.x=p[0].x;
109         li[n-1].ed.y=p[0].y;
110         bool flag=false;
111         for(i=0; i<n; i++)
112         {
113             for(j=i+2; j<n; j++)
114             {
115                     if(i == 0 && j == n-1)continue;
116                     /*if((li[i].st.x == li[j].st.x && li[i].st.y == li[j].st.y)
117                        || li[i].st.x == li[j].ed.x && li[i].st.y == li[j].ed.y
118                        || li[i].ed.x == li[j].st.x && li[i].ed.y == li[j].st.y
119                        || li[i].ed.x == li[j].ed.x && li[i].ed.y == li[j].ed.y)
120                         continue;*/
121                     if(segIntersect(li[i].st,li[i].ed,li[j].st,li[j].ed))
122                     {
123                         flag=true;
124                         break;
125                     }
126             }
127         }
128
129         if(flag || n<3)
130         {
131             printf("Figure %d: Impossible\n",cas++);
132         }
133         else
134         {
135             double ans=Area(n);
136             printf("Figure %d: %.2lf\n",cas++,ans);
137         }
138         printf("\n");
139     }
140     return 0;
141 }

zoj 1010 (线段相交判断+多边形求面积),布布扣,bubuko.com

时间: 2024-10-04 16:12:30

zoj 1010 (线段相交判断+多边形求面积)的相关文章

zoj 1010 Area 判断线段是否相交(把线段扩充一倍后 好处理) + 多边形求面积

题目来源: http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=10 题意:  给定n个点的, 如果这n个点不能形成多边形 以及 n < 3 时, 输出, "Impossible",  否则 输出 多边形的面积. 分析: 这题主要在 分析  n 个点 是否形成 多边形.  枚举 每条边,  看 这条边 是否与 其他 n - 3 条边 不规范相交. (当处理 其他 边时, 我们采用 扩充线段一倍) 代码如下: con

ACM1558两线段相交判断和并查集

Segment set Problem Description A segment and all segments which are connected with it compose a segment set. The size of a segment set is the number of segments in it. The problem is to find the size of some segment set. Input In the first line ther

poj 2653 (线段相交判断)

http://poj.org/problem?id=2653 Pick-up sticks Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 9531   Accepted: 3517 Description Stan has n sticks of various length. He throws them one at a time on the floor in a random way. After finishi

poj 1410 线段相交判断

http://poj.org/problem?id=1410 Intersection Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 11329   Accepted: 2978 Description You are to write a program that has to decide whether a given line segment intersects a given rectangle. An ex

POJ 1410 Intersection(线段相交&amp;&amp;判断点在矩形内&amp;&amp;坑爹)

Intersection 大意:给你一条线段,给你一个矩形,问是否相交. 相交:线段完全在矩形内部算相交:线段与矩形任意一条边不规范相交算相交. 思路:知道具体的相交规则之后题其实是不难的,但是还有个坑点就是题目里明明说给的是矩形左上角跟右下角的点,但实际上不是,需要重新判断一下...真坑. 1 struct Point 2 { 3 double x, y; 4 } A, B, C, D; 5 struct Line 6 { 7 Point a, b; 8 } L; 9 10 int n; 11

poj 1654 Area (多边形求面积)

链接:http://poj.org/problem?id=1654 Area Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 14952   Accepted: 4189 Description You are going to compute the area of a special kind of polygon. One vertex of the polygon is the origin of the orth

Area---poj1265(皮克定理+多边形求面积)

题目链接:http://poj.org/problem?id=1265 题意是:有一个机器人在矩形网格中行走,起始点是(0,0),每次移动(dx,dy)的偏移量,已知,机器人走的图形是一个多边形,求这个机器人在网格中所走的面积,还有就是分别求多边形上和多边形内部有多少个网格点: 皮克定理: 在一个多边形中.用I表示多边形内部的点数,E来表示多边形边上的点数,S表示多边形的面积. 满足:S:=I+E/2-1; 求E,一条边(x1,y1,x2,y2)上的点数(包括两个顶点)=gcd(abs(x1-x

POJ 1066 Treasure Hunt 线段相交判断

判断以宝藏的坐标和中点的坐标为线段的点是否与墙相交,求最少相交的墙的数量 中点算出来,枚举中点和墙 #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #define eps 1e-8 #define INF 1e9 using namespace std; const int maxn=100; typede

poj 2653 Pick-up sticks(几何线段相交判断)

Pick-up sticks Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 10949   Accepted: 4085 Description Stan has n sticks of various length. He throws them one at a time on the floor in a random way. After finishing throwing, Stan tries to fin