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
  • 相关阅读:
    js关闭浏览器事件,js关闭浏览器提示及相关函数
    js获取url传递参数,js获取url?号后面的参数
    js如何获取object类型里的键值
    在一个JS文件中引用另一个JS文件
    JSP上传大型视频文件到服务器,解决方案
    csharp上传大型视频文件到服务器,解决方案
    C#上传大型视频文件到服务器,解决方案
    C#.NET上传大型视频文件到服务器,解决方案
    ASP.NET上传大型视频文件到服务器,解决方案
    PHP上传大型视频文件到服务器,解决方案
  • 原文地址:https://www.cnblogs.com/hxer/p/5185147.html
Copyright © 2011-2022 走看看