uva 754 Treasure Hunt?! (线段位置判断并且求交点)

只需要枚举每个起点与终点之间有条线段与它相交。

代码:

    #include<cstdio>  
    #include<cstring>  
    #include<cstdlib>  
    #include<algorithm>  
    #define MAXN 1000  
    #define ESP 1e-8  
    using namespace std;  
    struct point   
    {  
        double x,y;  
        point(): x(.0), y(.0) {};  
        point(double _x,double _y) : x(_x),y(_y) {};  
        void input() { scanf("%lf %lf",&x,&y); }    
    };    
    struct line  
    {  
        point a,b;  
    };  
    double sgn(double d)  
    {   return d > ESP ? 1 : (d < -ESP ? -1 : 0);  
    }  
    point operator-(const point a,const point b)  
    {   return point(b.x-a.x , b.y-a.y);  
    }  
    double operator*(const point a,const point b)  
    {   return a.x*b.y - a.y*b.x;  
    }  
    bool operator==(const point a,const point b)  
    {   return sgn(a.x-b.x) == 0 && sgn(a.y-b.y) == 0;  
    }  
    bool jiaodian(point a,point b,point c,point d,point &p)  
    {  
        double s1 = (b-a) * (c-a) , s2 = (b-a) * (d-a),  
               s3 = (d-c) * (a-c) , s4 = (d-c) * (b-c);  
        if( sgn(s1) * sgn(s2) > 0 || sgn(s3) * sgn(s4) > 0)  
           return false;  
        p = point( (s2*c.x - s1*d.x) / (s2-s1),   
                   (s2*c.y - s1*d.y) / (s2-s1) );  
        return true;  
    }  
    bool pan(point a,point b,point c,point d)  
    {  
        double s1 = (b-a) * (c-a) , s2 = (b-a) * (d-a),  
               s3 = (d-c) * (a-c) , s4 = (d-c) * (b-c);  
        if( sgn(s1) * sgn(s2) >= 0 || sgn(s3) * sgn(s4) >= 0)   
           return false;  
        return true;  
    }  
    line ab[MAXN];  
    point d[MAXN],s;  
    int dn,n;  
    int max(int a, int b) { return a>b?a:b; }  
    int min(int a, int b) { return a<b?a:b; }  
    bool cmp(const point &a, const point &b)  
    {  
        if( sgn(a.x-b.x) != 0 )   
        {  if( sgn(a.x-b.x) < 0 ) return true;  
           else return false;  
        }  
        else   
        {  if( sgn(a.y-b.y) < 0)  return true;  
           else  return false;  
        }  
    }  
    int get(point a,point b)  
    {  
        int i,j,k = 0;  
        point c;  
        for(i=1;i<=n;i++)  
          if(pan(a, b, ab[i].a, ab[i].b))  
             k++;     
        return k;  
    }  
    int add(point a,point b)  
    {  
        int i,j,k,r,w,ans;  
        point c;  
        dn = 0;  
        d[++dn] = a;   
        d[++dn] = b;  
        for(i=1;i<=n;i++)  
        {  if( jiaodian(a, b, ab[i].a, ab[i].b, c) )  
              d[++dn] = c;  
        }  
        sort(d+1,d+dn+1,cmp);  
       // for(i=1;i<=dn;i++)  
         //   printf("%f %f \n",d[i].x,d[i].y);  
          
          
        ans = 1e8;  
        for(i=2;i<=dn;i++)  
        {  k = get(s, point( (d[i-1].x+d[i].x)/2, (d[i-1].y+d[i].y)/2 ) ) ;  
           //printf("%f %f %d\n",(d[i-1].x+d[i].x)/2, (d[i-1].y+d[i].y)/2,k);   
           ans = min(ans, k);  
        }  
        return ans;  
    }  
    void init()  
    {  
        int i,j,k,r,w;  
          
        //scanf("%d",&n);  
        for(i=1;i<=n;i++)  
        {  ab[i].a.input();  
           ab[i].b.input();  
        }   
        s.input();  
    }   
    void solve()  
    {  
        int ans = 1e8;  
        ans = min(ans, add(point(0,0), point(0,100)));  
        ans = min(ans, add(point(0,100), point(100,100)));  
        ans = min(ans, add(point(100,100), point(100,0)));  
        ans = min(ans, add(point(0,0), point(100,0)));  
        printf("Number of doors = %d\n",ans+1);  
    }  
    int main()  
    {  
        int t,i;  
        //scanf("%d",&t);  
        //for(i=1;i<=t;i++)  
        while(scanf("%d",&n) != EOF)  
        {  init();  
           solve();  
        }  
        return  0;  
    }  




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值