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;
}