poj 1066 Treasure Hunt

http://poj.org/problem?id=1066

這道直接暴力枚舉每個分割的小線段的中點,然後與寶藏的那個點相連,然後判斷與此線段相交的線段數,求出最小就行。

#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#define maxn 500000
using namespace std;

const double eps=1e-10;
const int inf=1<<30;
int t1,t2,t3,t4,t5,c;

int cmp(double x)
{
    if(fabs(x)<eps) return 0;
    if(x>0) return 1;
    return -1;
}

struct point
{
    double x,y;
    point() {}
    point(double a,double b):x(a),y(b) {}
    friend point operator -(const point &a,const point &b)
    {
        return point(a.x-b.x,a.y-b.y);
    }
    friend point operator *(const point &a,const double &b)
    {
        return point(a.x*b,a.y*b);
    }
    friend point operator /(const point &a,const double &b)
    {
        return point(a.x/b,a.y/b);
    }
} p[maxn];
point m[4][500000];

int cmp1(const point &a,const point &b)
{
    return a.x<b.x;
}

int cmp2(const point &a,const point &b)
{
    return a.y<b.y;
}

struct line
{
    point a,b;
    line() {}
    line(point x,point y):a(x),b(y) {};
} ll[maxn];

double det(const point &a,const point &b)
{
    return a.x*b.y-a.y*b.x;
}

bool segment(point a1,point a2,point b1,point b2)
{
    double c1=det(a2-a1,b1-a1),c2=det(a2-a1,b2-a1);
    double c3=det(b2-b1,a1-b1),c4=det(b2-b1,a2-b1);
    return cmp(c1)*cmp(c2)<0&&cmp(c3)*cmp(c4)<0;
}

void make(double x,double y)
{
    if(y==0)
    {
        m[0][t1].x=x;
        m[0][t1++].y=y;
    }
    else if(y==100)
    {
        m[1][t2].x=x;
        m[1][t2++].y=y;
    }
    else if(x==100)
    {
        m[2][t3].x=x;
        m[2][t3++].y=y;
    }
    else if(x==0)
    {
        m[3][t4].x=x;
        m[3][t4++].y=y;
    }
}

void inti()
{
    for(int i=1; i<=t1; i++)
    {
        p[c].x=(m[0][i].x+m[0][i-1].x)/2;
        p[c++].y=0;
    }
    for(int i=1; i<=t3; i++)
    {
        p[c].y=(m[2][i].y+m[2][i-1].y)/2;
        p[c++].x=100;
    }
    for(int i=1; i<=t2; i++)
    {
        p[c].x=(m[1][i].x+m[1][i-1].x)/2;
        p[c++].y=100;
    }
    for(int i=1; i<=t4; i++)
    {
        p[c].y=(m[3][i].y+m[3][i-1].y)/2;
        p[c++].x=0;
    }
}
int main()
{
    int T;
    while(scanf("%d",&T)!=EOF)
    {
        int n=T;
        double x1,y1,x2,y2;
        t1=1,t2=1,t3=1,t4=1,t5=0;
        c=0;
        while(T--)
        {
            scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
            make(x1,y1);
            make(x2,y2);
            point st(x1,y1);
            point st1(x2,y2);
            ll[t5].a=st;
            ll[t5++].b=st1;
        }
        m[0][0].x=0;
        m[0][0].y=0;
        m[0][t1].x=100;
        m[0][t1].y=0;
        m[2][t3].x=100;
        m[2][t3].y=100;
        m[2][0].x=100;
        m[2][0].y=0;
        m[1][0].x=0;
        m[1][0].y=100;
        m[1][t2].x=100;
        m[1][t2].y=100;
        m[3][0].x=0;
        m[3][0].y=0;
        m[3][t4].x=0;
        m[3][t4].y=100;
        sort(m[0],m[0]+t1+1,cmp1);
        sort(m[1],m[1]+t2+1,cmp1);
        sort(m[2],m[2]+t3+1,cmp2);
        sort(m[3],m[3]+t4+1,cmp2);
        inti();
        point pp,p1;
        scanf("%lf%lf",&pp.x,&pp.y);
        int ans=inf;
        for(int i=0; i<c; i++)
        {
            line l1(p[i],pp);
            int ans1=0;
            for(int j=0; j<t5; j++)
            {
                if(segment(l1.a,l1.b,ll[j].a,ll[j].b)) ans1++;
            }
            ans=min(ans,ans1);
        }
        if(n==0)
        {
            ans=0;
        }
        printf("Number of doors = %d\n",ans+1);
    }
    return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章