ZOJ 1648 Circuit Board(判断线段相交)

计算几何,思路挺简单的,基本的线段相交判断,各种模板各种整啊,出了繁琐以外不觉得有多少嚼头(有点嚣张了,面壁5秒)。

 

向量叉积,看下面的图,很NB(摘自:http://blog.csdn.net/xwebsite/archive/2010/07/31/5778325.aspx)

 

ZOJ 1648 Circuit Board(判断线段相交)_第1张图片

 

ZOJ 1648 Circuit Board(判断线段相交)_第2张图片

 

我的代码:

 

#include<stdio.h> #include<math.h> #include<string.h> #define max(a,b) a>b?a:b #define min(a,b) a<b?a:b #define N 2001 #define esp 0.000000001 struct point { double x,y; }; struct Line { point a,b; }line[N]; double xmult(point a1,point b1,point a2,point b2) { return (a1.x-b1.x)*(a2.y-b2.y)-(a2.x-b2.x)*(a1.y-b1.y); } int quick_judge(int i,int j) { point tmp; int flag_x,flag_y; //保证每条 line 中 a 为较小的点(在x轴上较左,在y轴上较下) if(line[i].a.x>line[i].b.x) tmp=line[i].a,line[i].a=line[i].b,line[i].b=tmp; if(line[j].a.x>line[j].b.x) tmp=line[j].a,line[j].a=line[j].b,line[j].b=tmp; //两条线段的 左端点中的较大值 <= 右端点中的较小值,就可以 x 轴上判断相交 double max_left=max(line[i].a.x,line[j].a.x),min_right=min(line[i].b.x,line[j].b.x); if(max_left > min_right) flag_x=0; else flag_x=1; if(line[i].a.y>line[i].b.y) tmp=line[i].a,line[i].a=line[i].b,line[i].b=tmp; if(line[j].a.y>line[j].b.y) tmp=line[j].a,line[j].a=line[j].b,line[j].b=tmp; double max_down=max(line[i].a.y,line[j].a.y),min_up=min(line[i].b.y,line[j].b.y); if(max_down > min_up) flag_y=0; else flag_y=1; if(flag_x && flag_y)return 1; //矩阵相交,不排斥,返回1 else return 0; } int judge_cross(int i,int j) { if(!quick_judge(i,j))return 0;//排斥,即矩阵不相交,那么线段一定不相交,返回0 if(xmult(line[i].a,line[j].a,line[j].b,line[j].a)*xmult(line[i].b,line[j].a,line[j].b,line[j].a)>0)return 0; return 1; } int main() { int i,j,t; while(~scanf("%d",&t)) { memset(line,0,sizeof(line)); for(i=0;i<t;i++) scanf("%lf%lf%lf%lf",&line[i].a.x,&line[i].a.y,&line[i].b.x,&line[i].b.y); if(t<=1) { printf("ok!/n");continue; } int cross=0; for(i=0;i<t;i++) { for(j=0;j<t;j++) { if(j==i)continue; if(judge_cross(i,j)) { cross=1;break; } } if(cross)break; } if(!cross)printf("ok!/n"); else printf("burned!/n"); } return 0; }

你可能感兴趣的:(struct,UP,2010)