POJ1066---Treasure Hunt (计算几何基础:线段相交)

来源:互联网 发布:有域名了怎么做网站 编辑:程序博客网 时间:2024/06/05 15:51

【题目来源】:https://vjudge.net/problem/POJ-1066
【题意】
给出一个100*100的矩形,中间有好多条线段分割成一个个独立的空间,然后给出宝藏的坐标,因为要拿到宝藏,所以,要炸掉一部分线段,并且,规定只能炸掉线段中点,问,最少炸掉几条线段才能够拿到宝藏?
【思路】
就像题面表示的那幅图,炸掉了一堵墙,以及一条线段,问题可以表述为从内部定点,到四周墙上的最少穿过的线段数量,然后,就想到了线段相交,遍历墙上所有点,判断从定点到该点与几条线段相交,但是两线段可能共端点,那么这个时候就不是相交了,所以数量不会增加。
特判:当n==0的时候,输出1,因为还有一堵墙,但是,重点中的重点,输入n之后,他还要输入一个点的坐标。。。。(已经冥思苦想了好久。。)
【代码】

#include<cmath>#include<cstdio>#include<list>#include<cstring>#include<algorithm>#define INF 1e9using namespace std;typedef long long LL;const double esp=1e-6;struct point{    double x,y;}a[100];int n;bool quick_check(point s,point t,point ss,point tt)//快速排斥实验{    if(min(s.x,t.x)<=max(ss.x,tt.x)&&min(s.y,t.y)<=max(ss.y,tt.y)&&min(ss.x,tt.x)<=max(s.x,t.x)&&min(ss.y,tt.y)<=max(s.y,t.y))        return 1;    else return 0;}double cross(point s,point t,point w)//叉乘{    return (s.x-t.x)*(w.y-t.y)-(w.x-t.x)*(s.y-t.y);}bool kua_li(point s,point t,point ss,point tt)//跨立实验{    if(!quick_check(s,t,ss,tt)) return false;    if(cross(s,t,ss)*cross(s,t,tt)>=-esp) return false;//除去共端点的情况,所以是>=-esp    if(cross(ss,tt,s)*cross(ss,tt,t)>=-esp) return false;    return true;}int main(){    while(~scanf("%d",&n))    {        int tot=0;        for(int i=0;i<n;i++)        {            scanf("%lf%lf",&a[tot++].x,&a[tot].y);            scanf("%lf%lf",&a[tot++].x,&a[tot].y);        }        scanf("%lf%lf",&a[tot].x,&a[tot].y);        if(n==0)        {            printf("Number of doors = 1\n");            continue;        }        int minn=INF;        for(int i=0;i<2*n;i++)        {            int num=0;            for(int j=0;j<n;j++)            {                if(kua_li(a[i],a[tot],a[j*2],a[j*2+1]))                {                   num++;                }            }            if(num<minn)                minn=num;        }        printf("Number of doors = %d\n",minn+1);    }}
原创粉丝点击