zoukankan      html  css  js  c++  java
  • 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;
    }
     
  • 相关阅读:
    NOI-OJ 2.2 ID:6261 汉诺塔
    NOI-OJ 2.2 ID:1696 逆波兰表达式
    NOI-OJ 2.2 ID:8758 2的幂次方表示
    NOI-OJ 2.2 ID:3089 爬楼梯
    NOI-OJ 1.13 ID:34 确定进制
    NOI-OJ 1.7 ID:21 单词替换
    NOI-OJ 1.13 ID:23 区间内的真素数
    【模板】欧拉筛法
    [SHOI2002]滑雪
    【Luogu1217】[USACO1.5]数字三角形(数塔问题) ——动态规划基础
  • 原文地址:https://www.cnblogs.com/zhangmingcheng/p/3952244.html
Copyright © 2011-2022 走看看