解题思路
题意:在一个矩形区域内,有n条线段,线段的端点是在矩形边上的,有一个特殊点,问从这个点到矩形边的最少经过的线段条数最少的书目,穿越只能在中点穿越。
根据myc巨爷所言,枚举每道墙的端点和p的连线,则这条线段和墙的交点的次数最小值即为需要炸墙的最小次数。记得最外面的四个顶点也算做端点,还有端点原本所在的那个墙不算,即不考虑共线的情况
PS:最后要加1,因为最外围的墙也要炸。
代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<vector>
#include<algorithm>
#define ll long long
#define db double
using namespace std;
int n,nn,cnt,ans;
double s,t;
struct node{
db x,y,xx,yy;
}f[100],v[100];
db work(node a,node b,node c)
{
return (b.x-a.x)*(c.y-a.y)-(b.y-a.y)*(c.x-a.x);
}
bool hh(node a,node b,node c)
{
if(c.x>=min(a.x,b.x)&&c.x<=max(a.x,b.x)&&c.y>=min(a.y,b.y)&&c.y<=max(a.y,b.y))
return 1;
return 0;
}
bool check(db ax,db ay,db bx,db by,db cx,db cy,db dx,db dy)
{
node a,b,c,d;
a.x=ax,a.y=ay,b.x=bx,b.y=by,c.x=cx,c.y=cy,d.x=dx,d.y=dy;
if((work(a,c,b)*work(a,b,d)>0)&&(work(c,b,d)*work(c,d,a)>0))
return 1;
/* if(work(a,b,d)==0&&hh(a,b,d))return 1;
if(work(a,b,c)==0&&hh(a,b,c))return 1;
if(work(c,d,a)==0&&hh(c,d,a))return 1;
if(work(c,d,b)==0&&hh(c,d,b))return 1;*/
return 0;
}
int main(){
scanf("%d",&n);
nn=n;
for(int i=1;i<=n;i++)
{
scanf("%lf%lf%lf%lf",&f[i].x,&f[i].y,&f[n+i].x,&f[n+i].y);
v[i].x=f[i].x,v[i].y=f[i].y,v[i].xx=f[i+n].x,v[i].yy=f[i+n].y;
}
n=n*2;
f[++n].x=0,f[n].y=0;
f[++n].x=0,f[n].y=100;
f[++n].x=100,f[n].y=0;
f[++n].x=100,f[n].y=100;
scanf("%lf%lf",&s,&t);
ans=1e9;
for(int i=1;i<=n;i++)
{
int w=0;
for(int j=1;j<=nn;j++)
{
if(check(f[i].x,f[i].y,s,t,v[j].x,v[j].y,v[j].xx,v[j].yy))
w++;
}
ans=min(ans,w);
}
printf("Number of doors = %d",ans+1);
}