水神的栅栏 | ||||||
|
||||||
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"); } } }