POJ 1127 Jack Straws (平面几何,求线段是否相交)

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
const double EPS = 1e-10;
double add(double a, double b){
	if (abs(a + b) < EPS * (abs(a) + abs(b))) return 0;
	return a + b;
}
struct P
{  
	double x,y;
	P(){}
	P (double x, double y): x(x),y(y){}

	P operator + (P p){
		return P(add(x , p.x), add(y , p.y));
	}
	P operator - (P p){
		return P(add(x ,-p.x), add(y , -p.y));
	}
	P operator * (double d){
		return P(x*d,y*d);
	}
	double dot(P p){ //内积
		return (add(x*p.x,y*p.y));
	}
	double det(P p){ //外积
		return (add(x*p.y , -y*p.x));
	}
};
bool on_seg(P p1, P p2, P q){ //判断点是否在线段上,
	return ((p1 - q).det(p2 - q) == 0 && (p1 - q).dot(p2 - q) <= 0);
}
P intersection(P p1, P p2, P q1, P q2 ){ //求两个线段的交点
	return p1 + (p2 - p1) * ((q2 - q1).det(q1 - p1) / (q2 - q1).det(p2 - p1));
}
P p[100],q[100];
bool jud[100][100];
int n,m;
int main(){
    while(scanf("%d",&n)== 1 && n){
    	for (int i = 0; i < n; i++){
    		scanf("%lf%lf",&p[i].x,&p[i].y);
    		scanf("%lf%lf",&q[i].x,&q[i].y);
    	}
		memset(jud,0,sizeof(jud));
		for (int i = 0; i < n; i++){
			jud[i][i] = 1;
			for (int j = 0; j < i; j++){
				if ((p[i] - q[i]).det(p[j] - q[j]) ==  0){ //判断两线段平行, 平行的线段有可能是有公共点的。重合一部分。
					jud[i][j] = jud[j][i] = on_seg(p[i],q[i],p[j]) || on_seg(q[i],p[i],q[j]);
				} else { //两线段不平行。
					P tt;
					tt = intersection(p[i],q[i],p[j],q[j]);
					jud[i][j] = jud[j][i] = (on_seg(p[i],q[i],tt) && on_seg(p[j],q[j],tt));
				}
			}
		}
		for (int k = 0; k < n; k++)
		for (int i = 0; i < n; i++)
		for (int j = 0; j < n; j++)
		jud[i][j] |= jud[i][k] && jud[k][j];    	

    	int s,t;
    	while(scanf("%d%d",&s,&t) == 2 && s){
    		if (jud[s-1][t-1] == 1) printf("CONNECTED\n"); else
    			printf("NOT CONNECTED\n");
    	}
    }
                      
	return 0;
}

猜你喜欢

转载自blog.csdn.net/kidsummer/article/details/81329014