ZOJ--1010:Area(线段判交问题)

来源:互联网 发布:http默认端口号8080 编辑:程序博客网 时间:2024/06/04 18:43
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


思路:这个题很明显,是个线段判交问题。。。先用跨立实验判断是否有相交的线段,若有则直接输出impossible、相反若没有则保留两位小数输出Area(注:这里面积输出要注意啊!我刚开始就是没注意这,让我想了半天 都没找到哪错了)

判断两条线断是否相交,首先我门要提出两个实验:

(1)快速排斥实验

(2)跨立实验

这两个实验的具体实现内容,大家可以看我的另一篇博客(是这个题的简化版): ZOJ--1648:Circuit Board(跨立实验线段判交)


最后 求面积的 就直接用叉乘的方法求。

叉乘:假设A、B、C、D四个点AB×CD=(A.x-B.x)*(C.y-D.y)-(A.y-B.y)*(C.x-D.x)


java AC代码:

import java.util.Scanner;public class ZOJ_1010 {static int n,flag=0;static double arr[][]=new double[1000][2];public static void main(String[] args) {Scanner s=new Scanner(System.in);while((n=s.nextInt())!=0){for(int i=0;i<n;i++){arr[i][0]=s.nextDouble();arr[i][1]=s.nextDouble();}if(flag!=0)System.out.println();flag++;System.out.print("Figure "+flag+": ");if(n<3||!judge()){//少于3个点就围不成一个多边形System.out.println("Impossible");continue;}if(judge())System.out.printf("%.2f\n",area());}}public static boolean judge(){for(int i=3;i<n;i++){//不判断最后一条,因为最后一个点是从第n个点到第0个点for(int j=1;j<i-1;j++)if(cross(i-1,i,j-1,j))return false;}for(int i=2;i<n-1;i++){//判断最后一条if(cross(i-1,i,n-1,0))return false;}return true;}public static boolean cross(int i1,int i2,int j1,int j2){double a=cal(arr[i1][0]-arr[j1][0],arr[i1][1]-arr[j1][1],arr[j2][0]-arr[j1][0],arr[j2][1]-arr[j1][1]);double b=cal(arr[j2][0]-arr[j1][0],arr[j2][1]-arr[j1][1],arr[i2][0]-arr[j1][0],arr[i2][1]-arr[j1][1]);double c=cal(arr[j1][0]-arr[i1][0],arr[j1][1]-arr[i1][1],arr[i2][0]-arr[i1][0],arr[i2][1]-arr[i1][1]);double d=cal(arr[i2][0]-arr[i1][0],arr[i2][1]-arr[i1][1],arr[j2][0]-arr[i1][0],arr[j2][1]-arr[i1][1]);if(a*b>=0&&c*d>=0)return true;return false;}public static double cal(double a,double b,double c,double d){return a*d-c*b;}public static double area(){double area=0;for(int i=2;i<n;i++){area+=cal(arr[i-1][0]-arr[0][0],arr[i-1][1]-arr[0][1],arr[i][0]-arr[0][0],arr[i][1]-arr[0][1]);}return Math.abs(area)/2.0;}}