HDU2150 Pipe

题目:http://acm.hdu.edu.cn/showproblem.php?pid=2150

判断线段是否相交的经典题目

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

#define _DEBUG 0
#define MAXN 30
#define MAXK 100
#define MAX(X,Y) (X)>(Y)?(X):(Y)
#define MIN(X,Y) (X)<(Y)?(X):(Y)

typedef struct{
	long long x;
	long long y;
}Point;
Point pipes[MAXN][MAXK];

long long crossMultiply(const Point &p1,
	const Point &p2,const Point p3){
		return (p2.x-p1.x)*(p3.y-p1.y)-(p3.x-p1.x)*(p2.y-p1.y);
}

bool inSegment(const Point &p1,
	const Point &p2,const Point p3){
		int minx=MIN(p1.x,p2.x);
		int maxx=MAX(p1.x,p2.x);
		int miny=MIN(p1.y,p2.y);
		int maxy=MAX(p1.y,p2.y);
		return (p3.x>=minx && p3.x<=maxx
			&& p3.y>=miny && p3.y<=maxy);
}

bool isIntersect(const Point &p1,
	const Point &p2,const Point p3,
	const Point p4){//p1--P2与p3--p4线段是否相交
		long long d1=crossMultiply(p1,p2,p3);
		long long d2=crossMultiply(p1,p2,p4);
		long long d3=crossMultiply(p3,p4,p1);
		long long d4=crossMultiply(p3,p4,p2);
		if((d1>0 && d2<0 || d1<0 && d2>0) 
			&& (d3>0 && d4<0 || d3<0 && d4>0)){
			return true;
		}
		if(d1==0 && inSegment(p1,p2,p3))
			return true;
		if(d2==0 && inSegment(p1,p2,p4))
			return true;
		if(d3==0 && inSegment(p3,p4,p1))
			return true;
		if(d4==0 && inSegment(p3,p4,p2))
			return true;
		return false;
}

bool check(int row,int col){
	assert(row>0 && col>0);
	int i,j;
	for(i=0;i<row;i++){
		for(j=1;;j++){
			if(pipes[i][j].x == 100000 && 
				pipes[i][j].y == 100000)//到达边界
				break;
			if(isIntersect(pipes[i][j-1],pipes[i][j],
				pipes[row][col-1],pipes[row][col])){//有交叉
					return true;
			}
		}
	}
	return false;
}
int main(){
#if _DEBUG == 1
	freopen("2150.in","r",stdin);
#endif
	int n,k;
	int i,j;
	while(scanf("%d",&n)!=EOF){
		bool flag = false;//1表示有交叉点,0表示没有
		for(i=0;i<n;i++){
			scanf("%d",&k);
			for(j=0;j<k;j++){
				scanf("%lld %lld",&pipes[i][j].x,&pipes[i][j].y);
				if(flag)//已判定有交叉点
					continue;
				if(i>=1 && j>=1 && check(i,j)){//如果检查与之前的点有交叉点
					flag=true;
				}					
			}
			//放置一不可能的点,作为边界
			pipes[i][k].x = 100000;
			pipes[i][k].y = 100000;
		}
		printf("%s\n",flag?"Yes":"No");
	}
	return 0;
}


 

发布了27 篇原创文章 · 获赞 4 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/hysfwjr/article/details/9281055