poj1127

来源:互联网 发布:与喝酒有关的网络红歌 编辑:程序博客网 时间:2024/04/29 16:39

链接:点击打开链接

题意:给出m对木棍的两个端点坐标,如果两根木棍有公共点则认为两根木棍相交,通过相连木棍间接连在一起的木棍也认为是相连的

代码1:

#include <stdio.h>#include <stdlib.h>#include <string.h>#include <iostream>#include <algorithm>using namespace std;struct node{    double stx,sty;    double enx,eny;};double cross1(node p,node q){     return (p.stx-p.enx)*(q.sty-p.sty)-(p.sty-p.eny)*(q.stx-p.stx);}double cross2(node p,node &q){     return (p.stx-p.enx)*(q.eny-p.sty)-(p.sty-p.eny)*(q.enx-p.stx);}int judge(node p,node q){     if(max(p.stx,p.enx)>=min(q.stx,q.enx)&&     max(q.stx,q.enx)>=min(p.stx,p.enx)&&     max(p.sty,p.eny)>=min(q.sty,q.eny)&&     max(q.sty,q.eny)>=min(p.sty,p.eny)&&     cross1(p,q)*cross2(p,q)<=0&&     cross1(q,p)*cross2(q,p)<=0)     return 1;     return 0;}                                               //通过快速排斥和跨立实验判断线段相交int par[50],ran[50];int find(int x){    if(x==par[x])    return x;    return par[x]=find(par[x]);}void unite(int x,int y){    x=find(x);    y=find(y);    if(x==y)    return;    if(ran[x]<ran[y])    par[x]=y;    else{        par[y]=x;        if(ran[x]==ran[y])        ran[x]++;    }}bool same(int x,int y){    return find(x)==find(y);}int main(){    int n,i,j,x,y;    node tmp,p[50];    while(scanf("%d",&n)!=EOF&&n){        memset(ran,0,sizeof(ran));        for(i=1;i<=n;i++)        par[i]=i;        for(i=1;i<=n;i++)        scanf("%lf%lf%lf%lf",&p[i].stx,&p[i].sty,&p[i].enx,&p[i].eny);        for(i=1;i<=n;i++)        for(j=i+1;j<=n;j++)        if(judge(p[i],p[j]))                    //用并查集维护        unite(i,j);        while(scanf("%d%d",&x,&y)&&(x||y)){            if(same(x,y))            puts("CONNECTED");            else            puts("NOT CONNECTED");        }    }    return 0;}


代码2:

#include <math.h>#include <stdio.h>#include <string.h>#include <stdlib.h>#include <iostream>#include <algorithm>using namespace std;const double EPS=1e-10;double add(double a,double b){    if(fabs(a+b)<EPS*(fabs(a)+fabs(b)))    return 0;    return a+b;}struct node{    double x,y;    node(){}    node(double x,double y):x(x),y(y){}    node operator+(node p){    return node(add(x,p.x),add(y,p.y));    }    node operator-(node p){    return node(add(x,-p.x),add(y,-p.y));    }    node operator*(double d){    return node(x*d,y*d);    }    double N(node p){    return add(x*p.x,y*p.y);    }    double W(node p){    return add(x*p.y,-y*p.x);    }};bool on_seg(node p1,node p2,node p){    return (p1-p).N(p2-p)<=0;}node cal(node p1,node p2,node q1,node q2){    return p1+(p2-p1)*((q2-q1).W(q1-p1)/(q2-q1).W(p2-p1));}int par[50],ran[50];int find(int x){    if(x==par[x])    return x;    return par[x]=find(par[x]);}void unite(int x,int y){    x=find(x);    y=find(y);    if(x==y)    return;    if(ran[x]<ran[y])    par[x]=y;    else{        par[y]=x;        if(ran[x]==ran[y])        ran[x]++;    }}                                               //通过外积和内积求出直线交点,再判断是否是线段交点bool same(int x,int y){    return find(x)==find(y);}int main(){    int n,i,j,x,y;    node tmp,p[50],q[50];    while(scanf("%d",&n)!=EOF&&n){        memset(ran,0,sizeof(ran));        for(i=1;i<=n;i++)        par[i]=i;        for(i=1;i<=n;i++)        scanf("%lf%lf%lf%lf",&p[i].x,&p[i].y,&q[i].x,&q[i].y);        for(i=1;i<=n;i++)        for(j=i+1;j<=n;j++){            if((p[i]-q[i]).W(p[j]-q[j])==0){    //平行时可能会重合单独考虑                if(on_seg(p[i],q[i],p[j])||on_seg(p[i],q[i],q[j])){                unite(i,j);                }            }            else{                tmp=cal(p[i],q[i],p[j],q[j]);                if(on_seg(p[i],q[i],tmp)&&on_seg(p[j],q[j],tmp)){                unite(i,j);                }            }        }        while(scanf("%d%d",&x,&y)&&(x||y)){            if(same(x,y))            puts("CONNECTED");            else            puts("NOT CONNECTED");        }    }    return 0;}


 

0 0
原创粉丝点击