zoukankan      html  css  js  c++  java
  • poj 3304 Segments

    Segments

    题意:给你100以内的n条线段,问你是否存在一条直线,使得题给的线段在这条直线上的“投影” 相交于一点;

    思路:
    1.先要将线段投影相交于一点转变为存在一条直线与所有的线段相交;
    很自然的想到,当存在一条直线使得所有的线段的投影都相交于一点时,过这点与该直线垂直的直线必定与所有的直线相交;

    2.如何判断这样的直线是否存在呢
    假设这样的直线存在,则这条直线的所能转动的极限位置就是与题目所给的线段的端点重合,这就直接枚举任意两条线段的两个端点;还有就是怎么知道所枚举出来的直线就与题给的线段相交呢?(重点)还是利用了叉乘的性质,前面TOYS那题,通过叉乘来判断出了点在线段的那一边,现在就直接判断两点(线段的端点)的叉积是否表示同时针即可~~~

    3.注意特判。。。,就是因为没判断n == 1的情况,WA了几次2333

    //  732K    32MS
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string.h>
    #include<algorithm>
    #include<map>
    #include<queue>
    #include<vector>
    #include<cmath>
    #include<stdlib.h>
    #include<time.h>
    using namespace std;
    #define MS0(a) memset(a,0,sizeof(a))
    #define esp 1e-6
    const int MAXN = 110;
    struct point{
        double x,y;
        point(){}
        point(double _x,double _y){
            x = _x; y = _y;
        }
        double operator *(const point &b)const{// 点向量叉乘
            return (x*b.y - y*b.x);
        }
        point operator -(const point &b)const{
            return point(x - b.x,y - b.y);
        }
        double dot(const point &b){    //点乘
            return x*b.x + y*b.y;
        }
        double dist(const point &b){
            return sqrt((x-b.x)*(x-b.x)+(y-b.y)*(y-b.y));
        }
        double  dist2(const point &b){
            return (x-b.x)*(x-b.x)+(y-b.y)*(y-b.y);
        }
        double len(){
            return sqrt(x*x+y*y);
        }
        double point_to_segment(point b,point c)//点a到“线段” bc的距离a.point_to_segment(b,c);
        {
            point v[4];
            v[1] = {c.x - b.x,c.y - b.y};
            v[2] = {x - b.x,y - b.y};
            v[3] = {x - c.x,y - c.y};
            if(v[1].dot(v[2]) < 0) return v[2].len();
            if(v[1].dot(v[3]) > 0) return v[3].len();
            return fabs(1.*(v[1]*v[2])/v[1].len());
        }
        double Xmult(const point &b,const point &c){   // 当a->b与a->c顺时针转时,返回正;
            return (b-*this)*(c-*this);
        }
        bool operator <(const point &b)const{
            return y < b.y||(fabs(y - b.y) < esp && x < b.x);
        }
        void input(){
            scanf("%lf%lf",&x,&y);
        }
    }p[MAXN];
    point s[MAXN],t[MAXN];
    int n,tot;
    bool cmp(const point &a,const point &b)
    {
        return fabs(a.x - b.x) < esp && fabs(a.y - b.y) < esp;
    }
    bool solve(point U,point L)
    {
        if(cmp(U,L)) return false;
        for(int i = 1;i <= n;i++){
            point a = s[i], b = t[i];
            if(a.Xmult(U,L) * b.Xmult(U,L) > esp) return false;
        }
        return true;
    }
    int main()
    {
        int T,i,j,x1,y1,x2,y2;
        cin>>T;
        while(T--){
            int flag = 0;
            scanf("%d",&n);
            for(i = 1;i <= n;i++){
                s[i].input(); t[i].input();
            }
            if(n < 3) flag = 1;    // ***
            for(i = 1;i < n && !flag;i++){
                for(j = i + 1;j <= n && !flag;j++){
                    if(solve(s[i],s[j])||solve(s[i],t[j])||solve(t[i],s[j])||solve(t[i],t[j])){
                        flag = 1;
                    }
                }
            }
            puts(flag?"Yes!":"No!");
        }
        return 0;
    }
    View Code
  • 相关阅读:
    八数码难题 (codevs 1225)题解
    小木棍 (codevs 3498)题解
    sliding windows (poj 2823) 题解
    集合删数 (vijos 1545) 题解
    合并果子 (codevs 1063) 题解
    等价表达式 (codevs 1107)题解
    生理周期 (poj 1006) 题解
    区间 (vijos 1439) 题解
    区间覆盖问题 题解
    种树 (codevs 1653) 题解
  • 原文地址:https://www.cnblogs.com/hxer/p/5185147.html
Copyright © 2011-2022 走看看