• POJ 1511 Pick-up sticks(线段相交)


    • 题意: 在二维平面给出很多棍子,求在最上面的棍子(不被覆盖)
    • 思路: 从前向后枚举线段是否跟后面线段有交点即可
    #include <cstdio>
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <string>
    #include <stdlib.h>
    #include <vector>
    #include <queue>
    #include <cmath>
    #include <stack>
    #include <map>
    #include <set>
    #define ll long long
    #define FOR(i,l,r) for(int i = l ; i <= r ;++i )
    #define inf 1<<30
    #define eps (1e-9)
    #define ALL(T)  T.begin(),T.end()
    #define lson(i)     i<<1
    #define rson(i)     (i<<1|1)
    using namespace std;
    typedef pair<int,int> pii;
    const int maxn = 100010;
    int sgn(double a){
        if(fabs(a)<eps) return 0;
        if(a>0) return 1;
        return -1;
    }
    struct point{
        double x,y;
        point(){}
        point(double _x,double _y):x(_x),y(_y){}
        void input(){
            scanf("%lf%lf",&x,&y);
        }
        point operator - (point b){
            return point(x-b.x,y-b.y);
        }
    };
    double sqr(double a){return a*a;}
    double det(point a,point b){    //叉乘
        return a.x * b.y - a.y * b.x;
    }
    struct line{
        point a,b;
        line(){}
        line(point _a,point _b):a(_a),b(_b){}
    };
    int n;
    int vis[maxn];
    int check(line la,line lb){
        // 端点均在线段两边,即为有交点
        if(sgn(det(la.a-lb.a,la.b-lb.a))*sgn(det(la.a-lb.b,la.b-lb.b))==-1
            && sgn(det(lb.a-la.a,lb.b-la.a))*sgn(det(lb.a-la.b,lb.b-la.b))==-1)
            return true;
        return false;
    
    }
    vector<line> ve;
    void solve(){
        ve.clear();
        memset(vis,0,sizeof vis);
        point a,b;
        FOR(i,1,n){
            scanf("%lf%lf%lf%lf",&a.x,&a.y,&b.x,&b.y);
            ve.push_back(line(a,b));
        }
        FOR(i,0,n-1){
            FOR(j,i+1,n-1){
                // printf("%lf %lf ",ve[i].a.x,ve[i].a.y);
                if(check(ve[i],ve[j])){
                    vis[i] = 1;
                    break;
                }
            }
        }
        printf("Top sticks:");
        int first = 1;
        FOR(i,0,n-1){
            if(!vis[i]){
                if(!first){
                    printf(",");
                }
                printf(" %d",i+1);
                first = 0;
            }
        }
        printf(".
    ");
    }
    
    int main(){
        while(scanf("%d",&n) && n!=0){
            solve();
        }
    
        return 0;
    }
    
    

    我们可以通过det的符号判断点对于线段的相对位置: 大于零右侧,小于零左侧,等于零在线段上

  • 相关阅读:
    多线程 C#解决方案小结
    程序员的灯下黑:Handson,Handson,Handson!
    有一家银行每天早上都在你的帐户里存入86,400
    3D流水线[引用]
    诸葛亮著作
    Vista 用户头像存储路径
    C# 关闭显示器的函数
    程序员的灯下黑:管理还是技术?兴趣优先
    VS1.4挤房+MH的登陆器
    失眠的调养
  • 原文地址:https://www.cnblogs.com/xxrlz/p/11317777.html
Copyright © 2020-2023  润新知