描述
You are to find the length of the shortest path through a chambercontaining obstructing walls. The chamber will always have sides at x = 0, x =10, y
= 0, and y = 10. The initial and final points of the path are always (0,5) and (10, 5). There will also be from 0 to 18 vertical walls inside thechamber, each with two doorways. The figure below illustrates such a chamberand also shows the path of minimal
length. 一个人
简要描述:一个人要从一个屋子里出去,屋子里有挡板,如上图在横坐标4处有0-2,7-8,9-10三个挡板,在横坐标为7处有0-3,4.5-6,7-10三个挡板,人从坐标(0,5)处出发,到(10,5)处出去,求经历的最短距离。
思路:这是纯数学分析,比较简单,只要判断出人要从那个位置出去就行了。
直接程序如下:
<span style="font-size:18px;"><strong>#include <cstdlib>
#include <iostream>
#include <stdio.h>
#include <cmath>
using namespace std;
int main()
{
float a[100]={0};
int i,j;
int num; //墙的数目;
float x,high; //x保存每一次出去点的横向坐标,high为出点的纵向坐标;
double sum; //记录总距离;
float k1,k2,c;
bool flag=false;
while(cin>>num && num!=-1)
{
fflush(stdin);
sum=0.0;x=0;high=5;
for(i=0;i<num*5;i++)
{
cin>>a[i]; //每组输入5个数,第一个为墙的横坐标,另外四个为挡板的纵向坐标;
}
for(i=0;i<num;i++)
{
j=i*5;
if(((a[j+1]<high)&&(a[j+2]>high))||((a[j+3]<high)&&(a[j+4]>high))) //直线通过;
{
flag=true;
}
else if(a[j+1]>high) //直线通过撞到第一块挡板;
{
if(flag) //若上一次是直线通过;
{
c=a[j];
}
else
{
c=a[j]-x;
}
k1=a[j+1]-high;
sum+=sqrt(c*c+k1*k1); //得到本次通过挡板时经过的最小距离;
high=a[j+1];
x=a[j];
flag=false;
}
else if((a[j+2]<high) && (a[j+3]>high)) //直线通过撞到第二块挡板;
{
if(flag)
{
c=a[j];
}
else
{
c=a[j]-x;
}
k1=high-a[j+2];
k2=a[j+3]-high;
if(k1>=k2) //判断是从第一块挡板的上部出去,还是从第二块挡板的下部出去;
{
sum+=sqrt(c*c+k2*k2);
high=a[j+3];
}
else
{
sum+=sqrt(c*c+k1*k1);
high=a[j+2];
}
x=a[j];
flag=false;
}
else if(a[j+4]<high) //直线通过撞到第三块挡板;
{
if(flag)
{
c=a[j];
}
else
{
c=a[j]-x;
}
k1=high-a[j+4];
c=a[j]-x;
sum+=sqrt(c*c+k1*k1);
high=a[j+4];
x=a[j];
flag=false;
}
}
if(high==5) //最后沿直线出去;
{
c=10-x;
sum+=c;
}
else //若是沿斜线出去,判断上一次出点纵坐标与5的大小;
{
c=10-x;
if(high>5)
{
k1=high-5;
}
else
{
k1=5-high;
}
sum+=sqrt(k1*k1+c*c);
}
printf("%.2f\n",sum);
}
system("pause");
return 0;
}
</strong></span>
输入:
1
5 4 6 7 8
2
4 2 7 8 9
7 3 4.5 6 7
-1
10.00
10.06