poj 1127 Jack Straws

第一道计算几何,直接抄的代码,不求甚解,搞不懂的以后做的题多了慢慢会懂的

#include<stdio.h>
#include<math.h>
#include<string>
#define MAX_N 15
#define MAX_M 10005
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);
	}
};
//判断点q是否在线段p1-p2上
bool on_seg(P p1,P p2,P q) {
	return (p1-q).det(p2-q) == 0 && (p1-q).dot(p2-q)<=0;
}
//计算直线p1-p2与q1-q2的交点
P intersection(P p1,P p2,P q1, P q2) {
	return p1+(p2-p1) * ((q2-q1).det(q1-p1) / (q2-q1).det(p2-p1));
}
//输入
int n;
P p[MAX_N],q[MAX_N];
int m;
int a[MAX_M],b[MAX_M];

bool g[MAX_N][MAX_N];	//相连关系图

void solve() {
	int i,j,k;
	for(i=1;i<n;i++) {
		g[i][i]=true;
		for(j=0;j<i;j++) {
			//判断i,j是否有公共点
			if ( ((p[i]-q[i]).det(p[j]-q[j]))==0 ) {
				//平行时
				g[i][j]=g[j][i]=on_seg(p[i],q[i],p[j])
								|| on_seg(p[i],q[i],q[j])
								|| on_seg(p[j],q[j],p[i])
								|| on_seg(p[j],q[j],q[i]);
			}
			else {
				//非平行时
				P r= intersection(p[i],q[i],p[j],q[j]);
				g[i][j]=g[j][i]= on_seg(p[i],q[i],r) && on_seg(p[j],q[j],r);

			}
		}
	}
	//通过Floyd-Warshall算法判断任意两点间是否相连
	for(k=0;k<n;k++) {
		for(i=0;i<n;i++) {
			for(j=0;j<n;j++) {
				g[i][j]|=g[i][k] && g[k][j];
			}
		}
	}
	for(i=0;i<m;i++) {
		puts(g[a[i]-1][b[i]-1]?"CONNECTED":"NOT CONNECTED");
	}
}
int main() {
#ifndef ONLINE_JUDGE
	freopen("in.txt","r",stdin);
#endif
	int i,j,x1,y1,x2,y2;
	while(~scanf("%d",&n)) {
		if (n==0) break;
		for(i=0;i<n;i++) {
			scanf("%lf%lf%lf%lf",&p[i].x,&p[i].y,&q[i].x,&q[i].y);
		}
		m=0;
		while(~scanf("%d%d",&a[m],&b[m])) {
			if (a[m]==0 && b[m]==0) break;
			m++;
		}
		solve();
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值