zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    mtk lk阶段的lcm流程
    MTK touchscreen 流程
    MTK DDR调试
    增加,删除GMS包
    最大最小背光亮度修改
    HDMI 8193 配置
    mtk6737t摄像头配置文件的编译
    camera调试命令
    Linux 终端显示 Git 当前所在分支
    ubuntu系统,关于源(source)的配置
  • 原文地址:https://www.cnblogs.com/forever97/p/poj1127.html
Copyright © 2011-2022 走看看