SDUTOJ2465:其实玩游戏也得学程序(bfs+优先队列+回溯)

http://acm.sdut.edu.cn/sdutoj/problem.php?action=showproblem&problemid=2465

题目描述

由于前两次的打击,ZYJ同学不再喜欢密码学,他喜欢上了游戏。某一 天,他要玩魔塔这个游戏,游戏规则是这样的,游戏地图的大小为N*M,一开始,ZYJ处于(0,0)点,ZYJ想去(N-1,M-1)点。但是通往目标的 路上有很多妖怪,每个妖怪都会打掉ZYJ不同数量的血量。现在ZYJ希望能够耗费最少的血量到达目的地。

但是他必须遵循以下规则:

1 他只能走上下左右四个方向。

2 每一个格可能为“.”“X”或者数字,“.”表示可以走,但是由于ZYJ身体虚弱,走的时候要扣掉1点血量值,“X”表示墙壁不可以走,数字表示这个怪物(数字大于等于1小于等于9)会打掉ZYJ的血量值。

而现在你的任务就是计算怎么样才能耗费最小的血量到达目的地。(毕竟ZYJ也不容易,连着受了两次打击,千万别再让他耗费过多的血量了,祖国需要这样的栋梁啊。。。。)

输入

 

输入包含多组数据,每一组数据第一行都有两个整数N,M,他们表示N*M的地图,接下来就是N行,长为M的迷宫。 (2<=N<=100,2<=M<=100),当输入的n=0,m=0的时候结束。

输出

 

如果无法到达目的地,就输出"GAME OVER.",如果可以找到,那么就把路径以样例的形式显示出来。输出的s代表的是耗费的血量的单位。不管能不能找到,在最后都输出一个"FINISH".

示例输入

5 6
.XX.1.
..X.2.
2...X.
...XX.
XXXXX.
0 0

示例输出

1s:(0,0)->(1,0)
2s:(1,0)->(1,1)
3s:(1,1)->(2,1)
4s:(2,1)->(2,2)
5s:(2,2)->(2,3)
6s:(2,3)->(1,3)
7s:(1,3)->(1,4)
8s:FIGHT AT (1,4)
9s:FIGHT AT (1,4)
10s:(1,4)->(1,5)
11s:(1,5)->(2,5)
12s:(2,5)->(3,5)
13s:(3,5)->(4,5)
FINISH
坑爹的题啊:
为么jx[]={0,0,1,-1},jy[]={1,-1,0,0}就A;jx[]={1,-1,0,0},jy[]={0,0,1,-1}就WA;什么后台数据??
这题是参考大神的代码,之前没思路就忍不住看了,要改啊,要努力思考,C++学的还是渣,感觉C++略难啊,不懂思想,回溯路径的思想还需加强。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
using namespace std;
typedef struct node
{
    int x,y,ans,num,pre;
    friend bool operator<(struct node a,struct node b)//现在还不懂啊
    {
        return a.ans>b.ans;
    }
} st;
st qq[100001];
int n,m;
char map[101][101];
int v[101][101],kj[100001];
int jx[]= {0,0,1,-1};
int jy[]= {1,-1,0,0};
int judge(int x,int y)
{
    if(x>=n||y>=m||x<0||y<0)
        return 0;
    if(map[x][y]=='X')
        return 0;
    return 1;
}
void bfs()
{
    int flag=0;
    int tt=1;
    memset(v,0,sizeof(v));
    priority_queue <st> q;
    st t,f;
    t.x=0;
    t.y=0;
    t.ans=0;
    t.num=1;
    t.pre=1;
    q.push(t);
    qq[tt]=t;
    v[0][0]=1;
    while(!q.empty())
    {
        t=q.top();
        q.pop();
        if(t.x==n-1&&t.y==m-1)
        {
            flag=1;
            break;
        }
        for(int i=0; i<4; i++)
        {
            f.x=t.x+jx[i];
            f.y=t.y+jy[i];
            if(v[f.x][f.y]==0&&judge(f.x,f.y))
            {
                if(map[f.x][f.y]=='.')
                {
                    f.ans=t.ans+1;
                    v[f.x][f.y]=1;
                    tt++;
                    f.num=tt;
                    f.pre=t.num;
                    qq[tt]=f;
                    q.push(f);
                }
                else
                {
                    f.ans=t.ans+map[f.x][f.y]-'0'+1;
                    v[f.x][f.y]=1;
                    tt++;
                    f.num=tt;
                    f.pre=t.num;
                    qq[tt]=f;
                    q.push(f);
                }
            }
        }
    }
    if(flag==0)
        printf("GAME OVER.
");
    else
    {
        int ww=0;
        for(int i=t.num; i!=1; i=qq[i].pre)
        {
            kj[ww++]=i;
        }
        for(int i=ww-1; i>=0; i--)
        {
            int y=kj[i];
            if(map[qq[y].x][qq[y].y]=='.')
            {
                printf("%ds:(%d,%d)->(%d,%d)
",qq[y].ans,qq[qq[y].pre].x,qq[qq[y].pre].y,qq[y].x,qq[y].y);
            }
            else
            {
                int nn = map[qq[y].x][qq[y].y]-'0';
                printf("%ds:(%d,%d)->(%d,%d)
",qq[y].ans-nn,qq[qq[y].pre].x,qq[qq[y].pre].y,qq[y].x,qq[y].y);
                for(int jj = 1; jj <= nn ; jj++)
                    printf("%ds:FIGHT AT (%d,%d)
",qq[y].ans-nn+jj,qq[y].x,qq[y].y);
            }

        }
    }
}
int main()
{
    int i,j;
    while(cin>>n>>m)
    {
        if(n==0&&m==0) break;
        getchar();
        for(i = 0 ; i < n ; i++)
            for(j = 0 ; j < m ; j++)
                cin>>map[i][j];
        bfs();
        printf("FINISH
");
    }
    return 0;
}
 
原文地址:https://www.cnblogs.com/zhangmingcheng/p/3952244.html