网址链接:http://acm.hdu.edu.cn/showproblem.php?pid=1026
题目大意:
给出1张n*m的地图,地图上面只有3种字符:数字,点和×,点表示可以通过,×表示不能通过,数字表示可以通过这个地方,但是必须在这个地方耗费时间打倒这地方的怪物。
题目已知了左上角和右下角不可能是×,求从左上角走到右下角的一条耗时最短的路径,并且输出该路径。
解题思路:
暂时没有想到别的,除了广搜。
题目大意:
给出1张n*m的地图,地图上面只有3种字符:数字,点和×,点表示可以通过,×表示不能通过,数字表示可以通过这个地方,但是必须在这个地方耗费时间打倒这地方的怪物。
题目已知了左上角和右下角不可能是×,求从左上角走到右下角的一条耗时最短的路径,并且输出该路径。
解题思路:
暂时没有想到别的,除了广搜。
源代码:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#include<set>
#include<map>
#include<vector>
#include<algorithm>
using namespace std;
char matri[101][101];
int a[10001];
int boo[101][101]; //表示到达每个点的最小时间
//注意:!!不能单纯的使用标记,因为很多地方虽然在步骤上是后来才到的但是时间却更小
struct node
{
int x,y; //表示坐标
int time; //到达该状态需要的时间
int pre; //表示上一状态的小标
}s[1000001];
int dir[4][2]={{1,0},{-1,0},{0,-1},{0,1}}; //表示4个不同方向的搜索
int n,m; //表示地图的长和宽
void print(int key)
{
int i,count,t,x,y,time,temp,t1;
printf("It takes %d seconds to reach the target position, let me show you the way.\n",s[key].time);
a[1]=key;
count=1;
while(s[key].pre!=-1)
{
a[++count]=s[key].pre;
key=s[key].pre;
}
time=1;
while(count>=1)
{
t=a[count]; //表示状态的下标
t1=a[count-1];
x=s[t].x; y=s[t].y;
if('1'<=matri[x][y] && matri[x][y]<='9') //说明该点是需要打斗的
{
temp=matri[x][y]-'0'; //在该点耽误的时间
while(temp--)
{
printf("%ds:FIGHT AT (%d,%d)\n",time++,x-1,y-1);
}
}
if(x==n && y==m) break;
printf("%ds:(%d,%d)->(%d,%d)\n",time++,x-1,y-1,s[t1].x-1,s[t1].y-1);
count--;
}
printf("FINISH\n");
}
void bfs()
{
int front,rear,i,j,key,x1,y1,time,time1;
int x2,y2,time2;
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)
{
boo[i][j]=99999999;
}
}
s[1].x=s[1].y=1;
s[1].pre=-1;
s[1].time=0;
boo[1][1]=0;
front=1; rear=2;
key=-1;
time=9999999;
while(front<rear)
{
x1=s[front].x; y1=s[front].y; time1=s[front].time;
if(x1==n && y1==m) //找到了终点,并且时间更小
{
time=time1;
key=front;
++front;
continue;
}
for(i=0;i<4;i++)
{
x2=x1+dir[i][0]; y2=y1+dir[i][1];
if(x2>n || x2<1 || y2>m || y2<1) continue;
if(matri[x2][y2]=='X') continue;
if(matri[x2][y2]=='.')
time2=time1+1;
else
time2=time1+matri[x2][y2]-'0'+1;
if(time2>=time) continue; //保证得到的时间比现有的时间小
if(boo[x2][y2]>time2) //得到的时间必须比该点已经有的时间小
{
boo[x2][y2]=time2;
s[rear].x=x2; s[rear].y=y2; s[rear].time=time2;
s[rear].pre=front;
rear++;
}
}
++front;
}
if(key==-1) //没有找到终点
printf("God please help our poor hero.\nFINISH\n");
else
print(key);
return;
}
int main()
{
int i,j;
//freopen("in.txt","r",stdin);
while(scanf("%d%d",&n,&m)==2)
{
getchar();
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)
{
scanf("%c",&matri[i][j]);
}
getchar();
}
bfs();
}
return 0;
}