POJ 1127 Jack Straws (计算几何)
【题目链接】 http://poj.org/problem?id=1127
【题目大意】
在二维平面中,给出一些木棍的左右端点,当木棍相交或者间接相交时
我们判断其连通,给出一些询问,问某两个木棍是否连通
【题解】
我们首先记录直接相连的木棍,然后对图跑一遍floyd算法,就能预处理出所有答案。
【代码】
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
using namespace std;
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));
}
const int MAX_N=12;
const int MAX_M=10000;
int n,m;
P p[MAX_N],q[MAX_N];
int a[MAX_M],b[MAX_M];
bool g[MAX_N][MAX_N];
void solve(){
memset(g,0,sizeof(g));
for(int i=0;i<n;i++){
g[i][i]=1;
for(int 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);
}
}
}
for(int k=0;k<n;k++){
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
g[i][j]|=g[i][k]&&g[k][j];
}
}
}
for(int i=0;i<m;i++){
puts(g[a[i]-1][b[i]-1]?"CONNECTED":"NOT CONNECTED");
}
}
bool init(){
scanf("%d",&n);
if(n==0)return 0;
for(int i=0;i<n;i++)scanf("%lf%lf%lf%lf",&p[i].x,&p[i].y,&q[i].x,&q[i].y);
int x,y; m=0;
while(scanf("%d%d",&x,&y),x&&y){
a[m]=x,b[m++]=y;
}return 1;
}
int main(){
while(init())solve();
return 0;
}
愿你出走半生,归来仍是少年

浙公网安备 33010602011771号