题意:
按顺序输入n个线段的两个坐标,然后多组输入判断两个线段是否是连接的(相交即为连接)。
思路:
计算几何 + floyd
考虑误差的加法运算
//考虑误差的加法运算
double add(double a,double b){
if(abs(a + b) < eps * (abs(a) + abs(b))) return 0;
else 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上
//判断点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;
//外积 = 0&&内积 <= 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));
}
代码实现:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long ll;
const int maxn = 2e5 + 5;
const double eps = 1e-10;
//考虑误差的加法运算
double add(double a,double b){
if(abs(a + b) < eps * (abs(a) + abs(b))) return 0;
else 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;
//外积 = 0&&内积 <= 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[maxn],q[maxn];//线段的两个端点
int m;
int a[maxn],b[maxn];
bool g[20][20];//相连关系图
void solve(){
for(int i = 0;i < n;i++){
g[i][i] = true;
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]);
}<C-S-F22
}
}
for(int i = 0;i < m;i++){
puts(g[a[i]-1][b[i]-1]?"CONNECTED":"NOT CONNECTED");
}
}
int main(){
while(~scanf("%d",&n)){
if(n == 0) break;
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 xa,xb;
m = 0;
while(~scanf("%d%d",&xa,&xb)){
if(xa == 0&&xb == 0) break;
a[m] = xa;
b[m] = xb;
m++;
}
solve();
}
return 0;
}