思路: 对 每一条 将正方形分割成许多小区域的 线段的顶点进行枚举 将该顶点与宝藏所在坐标相连 并与其它线段判定是否相交 找到相交次数最小的值 并加上1即为最终答案
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<cmath>
#include<cstdlib>
using namespace std;
const double eps = 1e-8;
struct point
{
double x,y;
}p[1000];
struct segment
{
point a,b;
}s[1000];
double cross(point a, point b, point o)//叉积
{
return (a.x-o.x)*(b.y-o.y)-(a.y-o.y)*(b.x-o.x);
}
int equal(double a)
{
if(fabs(a)<1e-6) return 0;
return a>0?1:-1;
}
bool check(point a, point b, point c, point d) //判相交
{
return equal(cross(a,c,d))*equal(cross(b,c,d))<=abs(eps) && equal(cross(a,b,c))*equal(cross(a,b,d))<=abs(eps);
}
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
point tem;
for(int i=0;i<n;i++)
{
scanf("%lf%lf%lf%lf",&s[i].a.x,&s[i].a.y,&s[i].b.x,&s[i].b.y);
p[i*2] = s[i].a;
p[i*2+1] = s[i].b;
}
scanf("%lf%lf",&tem.x,&tem.y);
int cnt, minn = 999999;
for(int i=0;i<2*n;i++)
{
cnt = 0;
for(int j=0;j<n;j++)
{
if(check(p[i],tem,s[j].a,s[j].b)&& i!=2*j && i!=2*j+1 ) //p[i]不能重复使用
cnt++;
}
minn = min(minn,cnt);
}
if(n==1||n==0)
minn = 0;
printf("Number of doors = %d\n",minn+1); //加上最外层墙
}
return 0;
}