记录路径的搜索——HDU1026 Ignatius and the Princess I

网址链接:http://acm.hdu.edu.cn/showproblem.php?pid=1026

题目大意:
给出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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值