zoukankan      html  css  js  c++  java
  • poj 1066 Treasure Hunt 线段相交判断

         宝藏在一个矩形的内部,矩形内有纵横交错的墙形成多个房间,求最少炸掉多少道墙可到达宝藏所在的房间,宝藏不会在墙上,炸点必须在墙的中间点上,不会超过两个的墙相交以一点。
        若起点和宝藏点连线的线段和某直线相交,那么无论你怎么绕你都要穿过这条直线才能到达宝藏点。所以我们可以这样做:枚举矩形边上的所有点做为起点,(不需要求中点做为起点)。连接起点、宝藏点,求出这条线段会和多少条其它的直线相交。然后加1(因为也要炸掉矩形边),即为所求答案。
     
    #include<stdio.h>
    #include<stdlib.h>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    struct point
    {
    double x,y;
    }p[100];
    double multi(point p0,point p1,point p2)
    {
    return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);
    }
    bool is(point s1,point e1,point s2,point e2) //判断线段相交
    {
    return (max(s1.x,e1.x)>=min(s2.x,e2.x))&&
    (max(s2.x,e2.x)>=min(s1.x,e1.x))&&
    (max(s1.y,e1.y)>=min(s2.y,e2.y))&&
    (max(s2.y,e2.y)>=min(s1.y,e1.y))&&
    (multi(s1,s2,e1)*multi(s1,e1,e2)>0)&&
    (multi(s2,s1,e2)*multi(s2,e2,e1)>0);
    }
    int main()
    {
    int i,j,n,min,num;
    while(scanf("%d",&n)!=EOF)
    {
    n*=2;
    for(i=0;i<n+1;i++)
    scanf("%lf%lf",&p[i].x,&p[i].y);
    min=0x7fffffff;
    for(i=0;i<n;i++)
    {
    num=0;
    for(j=0;j<n;j+=2)
    {
    if(i==j||i==j+1)  //起点要不在这条线段上
    continue;
    if(is(p[i],p[n],p[j],p[j+1]))
    num++;
    }
    if(num<min)
    min=num;
    }
    if(n==0) //要注意墙数为零的情况
    min=0;
    printf("Number of doors = %d\n",min+1);
    }
    return 0;
    }
            
     
     
     
     
  • 相关阅读:
    31天重构学习笔记9. 提取接口
    31天重构学习笔记4. 降低方法
    31天重构学习笔记8. 使用委派代替继承
    31天重构学习笔记11. 使用策略类
    31天重构学习笔记12. 分解依赖
    MyCat:第八章:MyCAT In Action中文版
    HDU 2041 超级楼梯
    CSU 1487 未覆盖顶点数量
    HDU 1712 ACboy needs your help
    HDU 2034 人见人爱AB
  • 原文地址:https://www.cnblogs.com/zxj015/p/2740223.html
Copyright © 2011-2022 走看看