OpenJudge 2.5 2727:仙岛求药

来源:互联网 发布:2017乘联会销量数据 编辑:程序博客网 时间:2024/06/04 20:02

2727:仙岛求药

Description
少年李逍遥的婶婶病了,王小虎介绍他去一趟仙灵岛,向仙女姐姐要仙丹救婶婶。叛逆但孝顺的李逍遥闯进了仙灵岛,克服了千险万难来到岛的中心,发现仙药摆在了迷阵的深处。迷阵由M×N个方格组成,有的方格内有可以瞬秒李逍遥的怪物,而有的方格内则是安全。现在李逍遥想尽快找到仙药,显然他应避开有怪物的方格,并经过最少的方格,而且那里会有神秘人物等待着他。现在要求你来帮助他实现这个目标。

Input
输入有多组测试数据. 每组测试数据以两个非零整数 M 和 N 开始,两者均不大于20。M 表示迷阵行数, N 表示迷阵列数。接下来有 M 行, 每行包含N个字符,不同字符分别代表不同含义:
1) ‘@’:少年李逍遥所在的位置;
2) ‘.’:可以安全通行的方格;
3) ‘#’:有怪物的方格;
4) ‘*’:仙药所在位置。
当在一行中读入的是两个零时,表示输入结束。
Output
对于每组测试数据,分别输出一行,该行包含李逍遥找到仙药需要穿过的最少的方格数目(计数包括初始位置的方块)。如果他不可能找到仙药, 则输出 -1。
Sample Input

8 8.@##...##....#.##.#.##....#.###.#.#...#...###.#....#.*...#...###6 5.*.#..#.....##.......#.......@9 6.#..#. .#.*.# .####. ..#... ..#... ..#... ..#... #.@.## .#..#. 0 0

Sample Output

108-1

题目分析:
本题目要求求得最短路径,因此用深度优先搜索极其容易超时,但更适合用广(宽)度优先搜索。广度优先搜索运用了FIFO队列queue,注意加上头文件queueusing namespace std
我们可以定义一个保存行走过程的结构体(MAZE),然后定义队列,格式为:

queue<MAZE> que;

一切准备工作(还要定义一个向量F)都做好了,就可以开始广度优先搜索了。由于我们的队列是MAZE类型的,我们就需要再定义一个MAZE类型的变量 FLAG,便于储存。最后输出就行了。

然后我们来看看作者的血泪史 -_-|||

  1. Time Limit Exceeded * 2
    循环这么多,不超时我都不信,只能说明广度优先搜索不熟。程序在这里:
#include<cstdio>#include<cstring>#include<queue>using namespace std;struct MAZE {int x,y,tot;};char maze[25][25];int main(){    //freopen("flagin.txt","r",stdin);    int F[4][2]={{-1,0},{1,0},{0,-1},{0,1}};    while(1)    {        queue<MAZE> que;        memset(maze,'#',sizeof(maze));        int r,c;        scanf("%d%d",&r,&c);        if(!r && !c) return 0;        for(int i=1;i<=r;i++)        {            scanf("%*c");            for(int j=1;j<=c;j++)            {                scanf("%c",&maze[i][j]);                if(maze[i][j]=='@')                {                    MAZE flag;flag.tot=0;flag.x=i;flag.y=j;                    que.push(flag);                }            }        }        bool Find=false;        while(!que.empty())        {            for(int i=0;i<4;i++)            {                int xx=que.front().x+F[i][0],yy=que.front().y+F[i][1];                if(maze[xx][yy]=='#') continue;                if(maze[xx][yy]=='*') {printf("%d\n",que.front().tot+1);Find=true;break;}                maze[xx][yy]='#';                MAZE flag;flag.tot=que.front().tot+1;flag.x=xx;flag.y=yy;                que.push(flag);            }            if(Find) break;            que.pop();        }        if(!Find) printf("-1\n");    }    return 0;}

2.Output Limit Exceeded * 1
这样的错误很常见。在编程过程中,调试是一个好习惯,但提交时一定要删去调试用的代码。不过我很不理解 ?_? ,这freopen的文件输入没有删不应该是超时或者是运行错误吗,怎么会输出超限。程序在这里:

#include<cstdio>#include<cstring>#include<queue>using namespace std;struct MAZE {int x,y,tot;};char maze[25][25];queue<MAZE> que;int main(){    freopen("flagin.txt","r",stdin);    int F[4][2]={{-1,0},{1,0},{0,-1},{0,1}};    while(1)    {        if(!que.empty()) que.pop();        memset(maze,'#',sizeof(maze));        int r,c;        scanf("%d%d",&r,&c);        if(!r && !c) return 0;        for(int i=1;i<=r;i++)        {            scanf("%*c");            for(int j=1;j<=c;j++)            {                scanf("%c",&maze[i][j]);                if(maze[i][j]=='@')                {                    MAZE flag;flag.tot=0;flag.x=i;flag.y=j;                    que.push(flag);                }            }        }        bool Find=false;        while(!que.empty())        {            for(int i=0;i<4;i++)            {                int xx=que.front().x+F[i][0],yy=que.front().y+F[i][1];                if(maze[xx][yy]=='#') continue;                if(maze[xx][yy]=='*') {printf("%d\n",que.front().tot+1);Find=true;break;}                maze[xx][yy]='#';                MAZE flag;flag.tot=que.front().tot+1;flag.x=xx;flag.y=yy;                que.push(flag);            }            if(Find) break;            que.pop();        }        if(!Find) printf("-1\n");    }    return 0;}

3.Runtime Error * 1
和上面的错误一样,莫名其妙的两次都忘了把freopen注释掉,但是…为什么上面是Output Limit Exceeded,而这个是Runtime Error?程序在这里:

#include<cstdio>#include<queue>#include<cstring>using namespace std;struct MAZE{    int x,y,tot;} ;char maze[25][25];int F[4][2]={{-1,0},{1,0},{0,-1},{0,1}}; //向量int main(){    freopen("flagin.txt","r",stdin);    while(1)    {        //初始化        queue<MAZE> que;        memset(maze,'#',sizeof(maze));        int r,c; bool FIND=false;        //输入        scanf("%d%d",&r,&c);        if(!r && !c) return 0;        for(int i=1;i<=r;i++)        {            scanf("%s",maze[i]+1);            for(int j=1;j<=c;j++)            {                if(maze[i][j]=='@')                {                    MAZE FLAG;FLAG.x=i;FLAG.y=j;FLAG.tot=0;                    que.push(FLAG);                }            }        }        //广度优先搜索        while(!que.empty())        {            for(int i=0;i<4;i++)            {                MAZE FLAG;                FLAG.x=que.front().x+F[i][0],FLAG.y=que.front().y+F[i][1],FLAG.tot=que.front().tot+1;                if(maze[FLAG.x][FLAG.y]=='#') continue;                if(maze[FLAG.x][FLAG.y]=='*') {printf("%d\n",FLAG.tot);FIND=true;break;}                maze[FLAG.x][FLAG.y]='#';                que.push(FLAG);            }            if(FIND) break;            que.pop();        }        if(!FIND) printf("-1\n");    }    return 0;}

4.Wrong Answer * 5
错的莫名其妙,为什么初始值为0,然后输出加1就不对了

#include<cstdio>#include<queue>#include<cstring>using namespace std;struct MAZE{    int x,y,tot;} ;char maze[25][25];int F[4][2]={{-1,0},{1,0},{0,-1},{0,1}}; //向量int flag(MAZE cpy,int r,int c){    queue<MAZE> que;    que.push(cpy);    while(!que.empty())    {        for(int i=0;i<4;i++)        {            MAZE FLAG;            FLAG.x=que.front().x+F[i][0];            FLAG.y=que.front().y+F[i][1];            FLAG.tot=que.front().tot+1;            if(FLAG.x<0 || FLAG.y<0 || FLAG.x>r || FLAG.y>c || maze[FLAG.x][FLAG.y]=='#') continue;            if(maze[FLAG.x][FLAG.y]=='*') {printf("%d\n",que.front().tot+1);return 0;}            maze[FLAG.x][FLAG.y]='#';            que.push(FLAG);        }        que.pop();    }    return -1;}int main(){    //freopen("flagout.txt","w",stdout);    while(1)    {        int r,c;        MAZE FLAG;        memset(maze,'#',sizeof(maze));        scanf("%d%d",&r,&c);        if(!r && !c) return 0;        for(int i=1;i<=r;i++)        {            scanf("%s",maze[i]+1);            for(int j=1;j<=c;j++)            {                if(maze[i][j]=='@')                    FLAG.x=i,FLAG.y=j,FLAG.tot=0;            }        }        printf("%d\n",flag(FLAG,r,c));    }    return 0;}

6.Accepted * 1
还是莫名其妙的,就对了?

#include<cstdio>#include<queue>#include<cstring>using namespace std;struct MAZE{    int x,y,tot;} ;char maze[25][25];int F[4][2]={{-1,0},{1,0},{0,-1},{0,1}}; //向量int flag(MAZE cpy,int r,int c){    queue<MAZE> que;    que.push(cpy);    while(!que.empty())    {        for(int i=0;i<4;i++)        {            MAZE FLAG;            FLAG.x=que.front().x+F[i][0];            FLAG.y=que.front().y+F[i][1];            FLAG.tot=que.front().tot+1;            if(FLAG.x<0 || FLAG.y<0 || FLAG.x>r || FLAG.y>c || maze[FLAG.x][FLAG.y]=='#') continue;            if(maze[FLAG.x][FLAG.y]=='*') return que.front().tot;            maze[FLAG.x][FLAG.y]='#';            que.push(FLAG);        }        que.pop();    }    return -1;}int main(){    //freopen("flagin.txt","r",stdin);    while(1)    {        int r,c;        MAZE FLAG;        memset(maze,'#',sizeof(maze));        scanf("%d%d",&r,&c);        if(!r && !c) return 0;        for(int i=1;i<=r;i++)        {            scanf("%s",maze[i]+1);            for(int j=1;j<=c;j++)            {                if(maze[i][j]=='@')                    FLAG.x=i,FLAG.y=j,FLAG.tot=1;            }        }        printf("%d\n",flag(FLAG,r,c));    }    return 0;}
原创粉丝点击