水神的栅栏 | ||||||
| ||||||
Description | ||||||
水神在赚了一笔钱之后,购买了一座庄园,做起了农场主,水神的农场都是靠栅栏围墙来分成很多部分并且围成外面的围墙的,但是最近一段时间,水神的庄园遭到了神兽的袭击,神兽撞破了很多处栅栏,这让水神非常苦恼,为了弄清楚自己的栅栏还有哪些地方时连着的,水神画了一张平面图,每一段栅栏在图上表示成一个线段,这些线段有的会相交,有的不会。 水神需要知道两段栅栏是否可以连起来。 | ||||||
Input | ||||||
有多组输入数据,每组数据: 第一行一个整数n表示水神农场的栅栏的个数(n<13) 接下来n行,每行四个整数x1,y1,x2,y2分别表示栅栏的两个端点坐标 然后下面若干行是对栅栏连接情况的询问,每行两个整数a,b表示水神想知道,栅栏a和栅栏b是否可以连起来。询问以0 0结束。 当n=0时输入结束 | ||||||
Output | ||||||
对于每次询问,如果栅栏a和b可以连起来,输出” CONNECTED”,否则输出:”NOT CONNECTED”. | ||||||
Sample Input | ||||||
2 0 2 0 0 0 0 0 1 1 1 2 2 1 2 0 0 2 0 2 0 0 1 0 2 0 1 2 0 0 0 | ||||||
Sample Output | ||||||
CONNECTED CONNECTED CONNECTED NOT CONNECTED | ||||||
Author | ||||||
曹振海 |
解题思路:
用线段相交的快速排斥试验和跨立试验来判断两个栅栏是否相交。至于线段相交的详解,我这里提供链接:
1、http://blog.csdn.net/mengxiang000000/article/details/50587203源自我的博客
2、http://blog.csdn.net/qq_33184171/article/details/51114511源自蒟犇白羊大神的博客
如果两个栅栏形成的线段能够相交,辣么就说明这两个栅栏能够CONNECTED。否者就是NOT CONNECTED。
AC代码:
#include<stdio.h>
#include<string.h>
#include<iostream>
using namespace std;
struct xianduan
{
int x1,x2,y1,y2;
}a[15];
struct point
{
int x,y;
}b[10];
int f[155];
int find(int x)
{
return f[x] == x ? x : (f[x] = find(f[x]));
}
void merge(int a,int b)
{
int A,B;
A=find(a);
B=find(b);
if(A!=B)
f[B]=A;
}
double multi(point p1,point p2,point p0)
{
return((p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y));
}
bool IsIntersected(point s1,point e1,point s2,point e2)//两个线段相交
{
return(max(s1.x,e1.x)>=min(s2.x,e2.x))&&
(max(s2.x,e2.x)>=min(s1.x,e1.x))&&
(max(s1.y,e1.y)>=min(s2.y,e2.y))&&
(max(s2.y,e2.y)>=min(s1.y,e1.y))&&
(multi(s1,s2,e1)*multi(s1,e1,e2)>=0)&&
(multi(s2,s1,e2)*multi(s2,e2,e1)>=0);
}
int main()
{
int n;
while(~scanf("%d",&n))
{
if(n==0)break;
for(int i=0;i<n;i++)
{
scanf("%d%d%d%d",&a[i].x1,&a[i].y1,&a[i].x2,&a[i].y2);
}
for(int i=1;i<=n;i++)
{
f[i]=i;
}
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
b[0].x=a[i].x1,b[0].y=a[i].y1;
b[1].x=a[i].x2,b[1].y=a[i].y2;
b[2].x=a[j].x1,b[2].y=a[j].y1;
b[3].x=a[j].x2,b[3].y=a[j].y2;
if(IsIntersected(b[0],b[1],b[2],b[3]))
{
merge(i,j);
}
}
}
while(1)
{
int xx,yy;
scanf("%d%d",&xx,&yy);
xx--;yy--;
if(xx==-1&&yy==-1)break;
if(find(xx)==find(yy))
{
printf("CONNECTED\n");
}
else printf("NOT CONNECTED\n");
}
}
}