链接:




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


Source: 
Asia 2001, Shanghai (Mainland China)


算法:计算几何 线段相交问题 面积问题


如果你不了解跨立实验判断线段相交问题,可以参考下我前面的一篇博客:ZOJ 1648 Circuit Board【跨立实验判断线段相交】


题意 + 思路:


给你 N  个点的坐标,点是按照顺序输入的。
每一个点都与它后面的那个点连成一条线段,最后一个点与起点相连。
求组成的多边形的面积。

注意:并不是直接求多边形的面积。
      首先要判断多边形的合法性:无论是凸多边形还是凹多边形都有可能合法。
                              这里的不合法指的是只要存在一条线段与不和它直接首尾相连的任意一条线段相交
                              就表示面积不可求,输出 impossible

            怎样算是相交?
            首先:直接两条线段两两跨立的当然算是相交了。
            其次:如果相于端点的也算是相交。

1.直接跨立相交,是肯定不行的。


2.相交于端点,也是非法的。
                     
 

关于线段相交于端点:画的详细点就是这样的图形也被认为是不可以求面积的
PS:图形来自 kuangbin 大神




所以这题的关键不是求面积,而是判断线段相交情况。

PS:本来第二次 WA 了马上就可以 AC 的了,判断线段相交的循环中 j < i 写错成了 j < 2
结果自己写这些简单题目的时候心态还是不行,最后就是纠结了一天多,然后又回到了开始的起点。
感谢 GJ 童鞋的提醒,要不然不知道乱改到什么时候去。

分析:

线段相交模板:自己画图理解下,还是推荐直接写自己的模板比较好了。

// = 0 表示,相交于端点也是认定为相交
bool SegmentProperIntersection(Point s1, Point e1, Point s2, Point e2) {
double c1 = Cross(s2-s1, e1-s1), c2 = Cross(e1-s1, e2-s1),
c3 = Cross(s1-s2, e2-s2), c4 = Cross(e2-s2, e1-s2);
if(c1*c2 >= 0 && c3*c4 >= 0) return true;
return false;
}

然后就是线段的比较判断问题:
注意: 是要与不和当前线段直接相连的每一条线段都比较。
          那么我们每次加入一个点,直接判断新形成的线段与前面所有出现过的不直接相连的比较就可以了

所以应该从第三条线段开始枚举。
因为第一条线段没有线段可以和它比较;
第二条线段前面只有一条线段,而这条线段又是和他直接相连的,所以不用比较。
这样一直到了第 N-1 条线段都可以这么判断下去。

然后注意到最后一条线段是终点和起点相连形成的,所以它不能和第一条线段比较,也不可以和第 n-1 条线段比较。2.


最后就是叉积求面积,不用解释了吧。

//叉积求面积 ,下标从 0 开始
double Area() {
double area = 0;
for(int i = 1; i < n-1; i++)
area += Cross(p[i]-p[0], p[i+1]-p[0]);
return fabs(area) / 2.0;
}


code:


#include<stdio.h>
#include<math.h>
#include<algorithm>
#include<iostream>
using namespace std; const int maxn = 1000+10;
int n; struct Point{
double x,y;
Point() {} Point(double _x, double _y) {
x = _x;
y = _y;
}
Point operator - (const Point &b) const{
return Point(x-b.x, y-b.y);
}
}p[maxn]; double Cross(Point a, Point b) { //叉积
return a.x*b.y - a.y*b.x;
} // = 0 表示,相交于端点也是认定为相交
bool SegmentProperIntersection(Point s1, Point e1, Point s2, Point e2) {
double c1 = Cross(s2-s1, e1-s1), c2 = Cross(e1-s1, e2-s1),
c3 = Cross(s1-s2, e2-s2), c4 = Cross(e2-s2, e1-s2);
if(c1*c2 >= 0 && c3*c4 >= 0) return true;
return false;
} bool haveCross() { //从第 三 条线段开始, 一直到第 N-1 条线段
for(int i = 2; i < n-1; i++) { //检查 Lin(i,i+1) 与前面每一条不直接相连的线段
for(int j = 1; j < i; j++) {
if(SegmentProperIntersection(p[i], p[i+1], p[j-1], p[j])) {
return true;
}
}
} //判断最后一条线段p[0]_p[n-1]
//从第二条线段一直比较到第 n-2 条线段
for(int i = 1; i < n-2 ; i++) { //p[i]__p[i+1]
if(SegmentProperIntersection(p[0],p[n-1],p[i],p[i+1])) {
return true;
}
}
return false;
} //叉积求面积
double Area() {
double area = 0;
for(int i = 1; i < n-1; i++)
area += Cross(p[i]-p[0], p[i+1]-p[0]);
return fabs(area) / 2.0;
} int main()
{
int test = 0;
while(scanf("%d", &n) != EOF) {
if(n == 0) break; double x,y;
for(int i = 0; i < n; i++) {
scanf("%lf%lf", &x,&y);
p[i] = Point(x,y);
} if(n < 3) { //如果小于三个点, 肯定不能求面积
printf("Figure %d: Impossible\n", ++test);
printf("\n");
continue;
} if(haveCross()) { //如果有线段相交的情况
printf("Figure %d: Impossible\n", ++test);
printf("\n");
continue;
}
else printf("Figure %d: %.2lf", ++test,Area());
printf("\n");
}
return 0;
} /**
几组全为 impossible 的数据
*/
/* 7
0 0
4 0
2 1
4 3
3 3
3 2
1 3 7
0 0
1 1
3 0
5 1
5 -1
3 0
1 -1 5
0 0
4 0
3 1
2 0
1 1 */

zoj 1010 Area【线段相交问题】的更多相关文章

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

    链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=10 Area Time Limit: 2 Seconds      Mem ...

  2. [ZOJ 1010] Area (计算几何)

    题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1010 题目大意:给你n个点,问你顺次连线能否连成多边形?如果能, ...

  3. [ZJU 1010] Area

    ZOJ Problem Set - 1010 Area Time Limit: 2 Seconds      Memory Limit: 65536 KB      Special Judge Jer ...

  4. 判断线段相交 -- 51nod 1264 线段相交

    http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1264 三角形的有向面积:a.x*b.y+b.x*c.y+c.x*a.y ...

  5. hdu 1086(判断线段相交)

    传送门:You can Solve a Geometry Problem too 题意:给n条线段,判断相交的点数. 分析:判断线段相交模板题,快速排斥实验原理就是每条线段代表的向量和该线段的一个端点 ...

  6. POJ 1127 Jack Straws (线段相交)

    题意:给定一堆线段,然后有询问,问这两个线段是不是相交,并且如果间接相交也可以. 析:可以用并查集和线段相交来做,也可以用Floyd来做,相交就是一个模板题. 代码如下: #pragma commen ...

  7. HDU 1558 Segment set( 判断线段相交 + 并查集 )

    链接:传送门 题意:输入一个数 n 代表有 n 组操作,P 是在平面内加入一条线段,Q x 是查询第 x 条线段所在相交集合的线段个数 例如:下图 5 与 1.2 相交,1 与 3 相交,2 与 4 ...

  8. POJ 1066 Treasure Hunt (线段相交)

    题意:给你一个100*100的正方形,再给你n条线(墙),保证线段一定在正方形内且端点在正方形边界(外墙),最后给你一个正方形内的点(保证不再墙上) 告诉你墙之间(包括外墙)围成了一些小房间,在小房间 ...

  9. POJ 2653 Pick-up sticks (线段相交)

    题意:给你n条线段依次放到二维平面上,问最后有哪些没与前面的线段相交,即它是顶上的线段 题解:数据弱,正向纯模拟可过 但是有一个陷阱:如果我们从后面向前枚举,找与前面哪些相交,再删除前面那些相交的线段 ...

随机推荐

  1. Android给ListView设置分割线Divider样式

    给ListView设置分割线,只需设置如下两个属性: android:divider="#000" //设置分割线显示颜色 android:dividerHeight=" ...

  2. leetcode第一刷_Interleaving String

    有关这样的字符串的题真是层出不穷啊,并且他们都有这样一个特点,就是递归的思路如此简单,但一定超时! 这个时候,dp就朝我们缓缓走来.递归超,dp搞!这道题的状态转移方程还是比較好写的,用ispart[ ...

  3. PHP 計算字符串長度函數

    PHP內置的字符串長度函數strlen無法正確處理中文字符串,它得到的只是字符串所占的字節數.對於GB2312的中文編碼,strlen得到的值是漢字個數的2倍,而對於UTF-8編碼的中文,就是3倍的差 ...

  4. Unix Shell 通配符、转义字符、元字符、特殊字符

    shell通配符: * 匹配0或多个字符 a*b a与b之间可以有任意长度的任意字符, 也可以一个也没有, 如aabcb, a01b, ab等 ? 匹配任意一个字符 a?b a与b之间有且只有一个字符 ...

  5. codevs1051单词接龙(栈)

    /* 看到n的范围就觉得这个不可能是DP啥的 因为这个接龙的规则十分的简单 只要前缀相同即可 所以先按字典序排一遍 这样保证符合规则的一定挨着 然后弄一个stack 每次拿栈顶元素看看待入栈的元素是否 ...

  6. codevs 3336 电话网络

    #include<iostream> #include<cstdio> #include<cstring> #include<queue> #defin ...

  7. json 序列化和反序列化

    Json串的格式: string strDataDiyList={"id":"1","name":"zhangsan", ...

  8. window.applicationCache事件,介绍

    1.关于applicationCache对象 在IE和Google中 为ApplicationCache对象 而在FF中为 OfflineResourceList对象 通过ApplicationCac ...

  9. sql - sum() 和 count() 函数的区别

    对sql一直都是蜻蜓点水,突然也觉得对这两个函数的区别有点朦胧,查了一下,在这里说一下: sum():主要用于累加求和. count():主要用于行(记录)的统计.

  10. iOS程序崩溃*** Terminating app due to uncaught exception 'CALayerInvalidGeometry', reason: 'CALayer position contains NaN: [37.5 nan]'

    今天上班打开昨天的程序运行,昨天跑的很溜的程序今天竟然crash了,好郁闷啊!下面附上crash的栈打印信息: 经过一番调试终于找到了原因,程序crash是因为CALayer的位置中含有不存在的数,就 ...