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

题目来源:

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

题意:  给定n个点的, 如果这n个点不能形成多边形 以及 n < 3 时, 输出, “Impossible”,
 否则 输出 多边形的面积。

分析:

这题主要在 分析  n 个点 是否形成 多边形。  枚举 每条边,  看 这条边 是否与 其他 n
- 3 条边 不规范相交。 (当处理 其他 边时, 我们采用 扩充线段一倍)

代码如下:


const int Max_N = 1010 ;
double add(double a, double b){
if( fabs(a + b) < EPS * ( fabs(a) + fabs (b)) ) return 0 ;
return a + b ;
}
struct Point{
double x, y ;
Point(){}
Point(double x , double y):x(x),y(y){}
Point operator +( Point p){
return Point(add(x , p. x) , add(y , p.y) ) ;
}
Point operator -( Point p){
return Point(add(x ,- p. x) , add(y ,- p.y) ) ;
}
Point operator * (double d){
return Point( x*d , y * d ) ;
}
double operator * (Point p){
return add(x * p.x , y * p.y) ;
}
double operator ^(Point p){
return add(x * p.y , -y*p.x) ;
}
}po[Max_N];
//判断点p是否在线段p1p2内
int on_segment(Point p1, Point p2, Point p){
if( ((p1 - p).x * (p2 - p).x <= 0) && ((p1 - p).y * (p2 - p).y <= 0))
return 1;
return 0;
}
struct Line{
Point st, ed;
Line(){}
Line(Point a, Point b){
st = a ;
ed = b ;
}
}line[Max_N *2];
//判断线段p1p2与q1q2 是否相交
int intersection(Line l1, Line l2 ){
Point p1 , p2 ,q1, q2 ;
p1 = l1.st ;
p2 = l1.ed ;
q1 = l2.st ;
q2 = l2.ed ;
double d1, d2, d3, d4;
d1 = (p2 - p1)^(q1 - p1) ;
d2 = (p2 - p1)^(q2 - p1) ;
d3 = (q2 - q1)^(p1 - q1) ;
d4 = (q2 - q1)^(p2 - q1) ;
if((d1 == 0 && on_segment(p1, p2, q1))
|| (d2 == 0 && on_segment(p1, p2, q2))
|| (d3 == 0 && on_segment(q1, q2, p1))
|| (d4 == 0 && on_segment(q1 ,q2 ,p2)))
return 1;
else if(d1 * d2 < 0 && d3 * d4 < 0)
return 1;
return 0;
}
int n;
bool judge(){
int i , j ;
for(i = 0 ; i < n ; i++)
for(j = i + 2; j <= n+ i - 2 ; j++)
if( intersection( line[i] , line[j]) )
return 0 ;
return 1;
}
int main(){
int i , j , k =1;
while(scanf("%d" , &n) && n){
double area = 0.0 ;
for(i = 0 ; i < n ; i++)
scanf("%lf%lf", &po[i].x , &po[i].y) ;
for(i =0 ;i < n ; i++){
line[i].st = po[i];
line[i].ed = po[(i+1) % n ] ;
}
for(i = 0 ; i< n ; i++) // 把线段扩展一倍时,特别好处理, 与线段不相邻的其他线段
line[n + i] = line[i] ;
if( k != 1) puts("") ;
printf("Figure %d: ", k++) ;
if(n < 3)
{
printf("Impossible\n") ;
continue ;
}
if(judge()){
for(i = 0 ;i < n ; i++)
area += po[i]^po[ (i+1) % n ] ;
area = area < 0 ? -area : area ;
printf("%.2lf\n" , area / 2.0 ) ;
}
else{
printf("Impossible\n") ;
}
}
return 0;
}

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

时间: 2024-10-23 08:47:10

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

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

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

[ZOJ 1010] Area (计算几何)

题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1010 题目大意:给你n个点,问你顺次连线能否连成多边形?如果能,就输出多边形面积. 面积用向量的叉积去算.然后能否连成多边形就是看这条线跟之前的线有没有交点. 这些在大白书上都有板子.. 代码: 1 #include <cstdio> 2 #include <cstdlib> 3 #include <string> 4 #include

ZOJ 1010 Area 求任意多边形面积

主要判断是否是多边形:1.n<3 : 2.非相邻两条线段不相交 #include <iostream> #include <cmath> #include <stdio.h> using namespace std; #define eps 1e-8 int sig(double x) { if(x<-eps) return -1; if(x>eps) return 1; return 0; } struct point { double x,y; }

POJ 1127 Jack Straws ( 求直线交点, 判断线段是否相交(含端点) )

题目:传送门 题意: 给你 n 条线段的两个端点, 然后有多次询问, 每次询问, 问你线段 x 和 线段 y 是否相交. 若线段 A 和线段 B 相交且线段 A 和线段 C 相交,那么线段 B 和线段 C 相交.     1 < n < 13 题解: 暴力求线段是否相交, 然后再跑个 Floyd 或者并查集都可以的. #include <iostream> #include <stdio.h> #include <string.h> #include <

zoj 1648 判断线段是否相交

链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=648 Circuit Board Time Limit: 2 Seconds      Memory Limit: 65536 KB On the circuit board, there are lots of circuit paths. We know the basic constrain is that no two path cross each other,

Jack Straws(判断线段是否相交 + 并查集)

/** http://acm.tzc.edu.cn/acmhome/problemdetail.do?&method=showdetail&id=1840  题意: 判断线段是否相交  (包括间接相交) 输入: N(代表有n条线段) sx  sy  ex  ey(一条直线的两端点的坐标) : : : a b(判断第a条和第b条线段是否相交) : : : 0 0输入0 0 询问结束 输出:若相交输出  CONNECTED 否则         NOT CONNECTED */ #includ

判断两线段是否相交

今日集训第一日,遇到了判断线段相交问题.跟面积问题一样,这个同样可以用叉积来解决. 数学原理证明: 首先引出计算几何学中一个最基本的问题:如何判断向量在的顺时针方向还是逆时针方向? 把p0定为原点,p1的坐标是(x1,y1),p2的坐标是(x2,y2).向量的叉积(cross product)实际上就是矩阵的行列式: 代码实现: 1 int direction(Point p0, Point p1, Point p2) { 2 int px02 = p2.x - p0.x; 3 int py02

判断两个线段是否相交

我们的问题是这样的:给定一条线段的起点为$A_1$.终点为$A_2$,另一条线段的起点为$B_1$.终点为$B_2$,问线段$A_1A_2$和线段$B_1B_2$是否相交? 我们首先解释一下,两条线段相交的概念是指,存在一个点,这个点同时在两条线段上. 方法一(解方程法): 容易知道,线段$A_1A_2$上的点的集合为$A = A_1 * (1 - r_1) + A_2 * r_1$,其中$r_1 \in [0, 1]$:同理,线段$B_1B_2$上的点的集合为$B = B_1 * (1 - r