题意:给出一个100*100的正方形区域,通过若干连接区域边界的线段将正方形区域分割为多个不规则多边形小区域,然后给出宝藏位置,要求从区域外部开辟到宝藏所在位置的一条路径,使得开辟路径所需要打通的墙壁数最少("打通一堵墙"即在墙壁所在线段中间位置开一空间以连通外界),输出应打通墙壁的个数(包括边界上墙壁)。
思路:枚举每一个入口,在所有的情况中取穿墙数最少的输出即可,枚举每一个入口的时候,并不用枚举每条边的中间点,直接枚举该线段的两个顶点就行(因为要经过一个墙,那么从线段的任意地方进去都行,不必要每次从线段的中点过去),将枚举的顶点与终点(即宝藏所在位置)连成线段,然后就是判断剩下的线段与该线段相交的问题了(注意这里是严格相交),最后得出的数字加1即为结果(因为还有边界墙),还有就是需要特别处理n=0时的情况。
这题不是很严格,有点小问题。(图和题意不对应)。
#include<stdio.h>
#define N 100
struct node
{
double x,y;
}p[N],en;
struct pp
{
node a,b;
}line[N];
double multi(node a,node b,node c)
{
return ((a.x-c.x)*(b.y-c.y)-(a.y-c.y)*(b.x-c.x));
}
int main()
{
int n,j=1,m,min,ans,i;
double a,b,c,d,t1,t2,t3,t4;
scanf("%d",&n);
for(i=1;i<=n;i++)
{
scanf("%lf%lf%lf%lf",&a,&b,&c,&d);
p[j].x=a;p[j++].y=b;p[j].x=c;p[j++].y=d;
line[i].a.x=a;line[i].a.y=b;
line[i].b.x=c;line[i].b.y=d;
}
m=j;min=99999999;
scanf("%lf%lf",&en.x,&en.y);
for(i=1;i<m;i++)
{
ans=1;
for(j=1;j<=n;j++)
{
t1=multi(p[i],en,line[j].a);
t2=multi(p[i],en,line[j].b);
t3=multi(line[j].a,line[j].b,p[i]);
t4=multi(line[j].a,line[j].b,en);
if(t1*t2<0&&t3*t4<0)//严格小于0
ans++;
}
if(ans<min)
min=ans;
}
if(n==0)//注意n=0 的情况,哎,老是忘记考虑特殊情况,一定要记住。
printf("Number of doors = %d\n",1);
else
printf("Number of doors = %d\n",min);
return 0;
}
poj 1066
最新推荐文章于 2022-01-25 16:34:05 发布