Ignatius and the Princess I

来源:互联网 发布:最新网络币 编辑:程序博客网 时间:2024/05/19 12:17

Ignatius and the Princess I
Time Limit : 2000/1000ms (Java/Other) Memory Limit : 65536/32768K (Java/Other)
Total Submission(s) : 14 Accepted Submission(s) : 7
Special Judge
Font: Times New Roman | Verdana | Georgia
Font Size: ← →
Problem Description
The Princess has been abducted by the BEelzebub feng5166, our hero Ignatius has to rescue our pretty Princess. Now he gets into feng5166’s castle. The castle is a large labyrinth. To make the problem simply, we assume the labyrinth is a N*M two-dimensional array which left-top corner is (0,0) and right-bottom corner is (N-1,M-1). Ignatius enters at (0,0), and the door to feng5166’s room is at (N-1,M-1), that is our target. There are some monsters in the castle, if Ignatius meet them, he has to kill them. Here is some rules:

1.Ignatius can only move in four directions(up, down, left, right), one step per second. A step is defined as follow: if current position is (x,y), after a step, Ignatius can only stand on (x-1,y), (x+1,y), (x,y-1) or (x,y+1).
2.The array is marked with some characters and numbers. We define them like this:
. : The place where Ignatius can walk on.
X : The place is a trap, Ignatius should not walk on it.
n : Here is a monster with n HP(1<=n<=9), if Ignatius walk on it, it takes him n seconds to kill the monster.

Your task is to give out the path which costs minimum seconds for Ignatius to reach target position. You may assume that the start position and the target position will never be a trap, and there will never be a monster at the start position.

Input
The input contains several test cases. Each test case starts with a line contains two numbers N and M(2<=N<=100,2<=M<=100) which indicate the size of the labyrinth. Then a N*M two-dimensional array follows, which describe the whole labyrinth. The input is terminated by the end of file. More details in the Sample Input.

Output
For each test case, you should output “God please help our poor hero.” if Ignatius can’t reach the target position, or you should output “It takes n seconds to reach the target position, let me show you the way.”(n is the minimum seconds), and tell our hero the whole path. Output a line contains “FINISH” after each test case. If there are more than one path, any one is OK in this problem. More details in the Sample Output.

Sample Input
5 6
.XX.1.
..X.2.
2…X.
…XX.
XXXXX.
5 6
.XX.1.
..X.2.
2…X.
…XX.
XXXXX1
5 6
.XX…
..XX1.
2…X.
…XX.
XXXXX.

Sample Output
It takes 13 seconds to reach the target position, let me show you the way.
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
It takes 14 seconds to reach the target position, let me show you the way.
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)
14s:FIGHT AT (4,5)
FINISH
God please help our poor hero.
FINISH
fang子救公主的故事,相传很久很久以前。。。。
然后我们这么救吧,碰到一个士兵,两下就能打死他,没碰到,当然我们要一步一步的走,(体力值是血啊。。),然后找到公主,过上性福的生活~
我们可以倒过来看,从公主的地方走回去,怎么走呢,我们用广搜,每次搜索当前点,用step记录他的步数,嘿嘿,那样到(1,1)时就完成咯,我们设置一个前驱值pre,这样每走一步,用,队列里面新进入一个ed,st赋给pre,因为我们可是要提前判断pre是否等于-1呢,关于这个我很慌,因为是看别人代码的,为什么不等于0呢?,我不加宽边界啊,我很纳闷,那样也能一步一步的输出步骤呀,是go还是fight、好了,不聊了,代码如下:

#include<cstdio>#include<cstring>#include<queue>#include<algorithm>#include<iostream>#define INF = maxn*maxn*10;using namespace std;const int maxn = 110;int map[maxn][maxn];int vist[maxn][maxn];char str[maxn];int n,m;int dir[4][2] = {{0,1}, {0,-1}, {-1,0}, {1,0}};struct node //  优先队列;{    int x,y;    int step;    bool operator < (const node &b) const    {        return b.step < step;    }};struct Pre//前驱点{    int px, py;} pre[maxn][maxn];void bfs(){    node st,ed;    priority_queue<node>Q;    int i;    while(!Q.empty())    Q.pop();    st.x=n,st.y=m;    st.step=map[n][m];    pre[n][m].px=-1;    Q.push(st);    memset(vist,0,sizeof(vist));    vist[n][m]=1;    while(!Q.empty())    {        st=Q.top();        Q.pop();        if(st.x==1&&st.y==1)        {            printf("It takes %d seconds to reach the target position, let me show you the way.\n",st.step);            int step=1;            int x=st.x,y=st.y;            int nx=pre[x][y].px,ny=pre[x][y].py;            while(pre[x][y].px!=-1)            {                printf("%ds:(%d,%d)->(%d,%d)\n",step++,x-1,y-1,nx-1,ny-1);                while(map[nx][ny]--)                {                    printf("%ds:FIGHT AT (%d,%d)\n",step++,nx-1,ny-1);                }                x=nx,y=ny;                nx=pre[x][y].px,ny=pre[x][y].py;            }            printf("FINISH\n");            return;        }        for(i=0; i<4; i++)        {            ed.x=st.x+dir[i][0];            ed.y=st.y+dir[i][1];            if(map[ed.x][ed.y]>=0&&!vist[ed.x][ed.y])            {                vist[ed.x][ed.y]=1;                ed.step=st.step+1+map[ed.x][ed.y];                pre[ed.x][ed.y].px=st.x;//前驱的信息                pre[ed.x][ed.y].py=st.y;                Q.push(ed);            }        }    }    printf("God please help our poor hero.\n");    printf("FINISH\n");    return;}int main(){    int i,j;    char c;    while(scanf("%d%d",&n,&m)!=EOF)    {        gets(str);        for(i=0; i<=n+1; i++)            for(j=0; j<=m+1; j++)            {                map[i][j]=-1;//边界加宽            }        for(i=1; i<=n; i++)        {            for(j=1; j<=m; j++)            {                scanf("%c",&c);                if(c!='X')                {                    if(c=='.')                        map[i][j]=0;                    else map[i][j]=c-'0';                }            }            gets(str);        }        bfs();    }    return 0;}
0 0