首页 > 代码库 > 仙岛求药

仙岛求药

#include<iostream>
#include<cmath>
#include<cstdio>
#include<algorithm>
#include<queue>
using namespace std;
char map[101][101];
int step=9999999;
int yaox[10010],yaoy[10010],book[101][101],n,m;
int road(int a,int b,int x,int y)
{
    return abs(x-a)+abs(y-b);//A* 横竖的大概路径,方便减少路径数,优化时间
}
int bfs(int a,int b,int x,int y)
{
    memset(book,0,sizeof(book));
    int nx,ny;
    queue <int> Qx;//存横竖坐标
    queue <int> Qy;
    Qx.push(a);//当前点坐标进队
    Qy.push(b);
    while(!Qx.empty())//队不为空
    {
        nx=Qx.front(),ny=Qy.front();//队首元素
        if(nx==x&&ny==y)//到达终点
        {
            return book[nx][ny];
        }
        Qx.pop();
        Qy.pop();
        if(book[nx-1][ny]==0 && map[nx-1][ny]!=# && nx>0)//判断是否走过,是否能走,是否出界
        {
            Qx.push(nx-1);
            Qy.push(ny);
            book[nx-1][ny]=book[nx][ny]+1;//步数加一
        }
        if(book[nx+1][ny]==0 && map[nx+1][ny]!=# && nx<=n)
        {
            Qx.push(nx+1);
            Qy.push(ny);
            book[nx+1][ny]=book[nx][ny]+1;
        }
        if(book[nx][ny-1]==0 && map[nx][ny-1]!=# && ny>0)
        {
            Qx.push(nx);
            Qy.push(ny-1);
            book[nx][ny-1]=book[nx][ny]+1;
        }
        if(book[nx][ny+1]==0 && map[nx][ny+1]!=# && ny<=m)
        {
            Qx.push(nx);
            Qy.push(ny+1);;
            book[nx][ny+1]=book[nx][ny]+1;
        }
    }
    return 0;
}
int main()
{
    while(cin>>n>>m)
    {
        int i,j,k=1,x,y,s1,s2;
        if(n==0&&m==0)
        {
            break;
        }

        for(i=1;i<=n;i++)
        {
            for(j=1;j<=m;j++)
            {
                cin>>map[i][j];
                if(map[i][j]==@)//李逍遥坐标
                {
                    x=i;
                    y=j;
                }
                if(map[i][j]==s)//婶婶坐标
                {
                    s1=i;
                    s2=j;
                }
            }
        }
        int minans=99999999;
        for(i=1;i<=n;i++)
        {
            for(j=1;j<=m;j++)
            {
                if(map[i][j]==*)//有药
                {
                    int yao;
                    yao=road(i,j,x,y);
                    yao+=road(i,j,s1,s2);
                    if(yao<minans)
                    {
                        int s=0;
                        s+=bfs(x,y,i,j);
                        s+=bfs(i,j,s1,s2);
                        if(s<minans)
                            minans=s;//更新最大值
                    }
                }
            }
        }
        cout<<minans<<endl;
    }
    //system("puase");
    return 0;
}

 


下面有题目,主要是一个深搜,用了A*算法,求出每条路的大概值,找最优解。(比较到一个药再到终点的直线距离是否比上到一个药到终点的实际距离要长,长的话直接舍去,短的话再求实际距离。)

 

仙岛求药(二)
难度级别:C; 运行时间限制:1000ms; 运行空间限制:256000KB; 代码长度限制:2000000B
试题描述
咳,上回说到李逍遥去求药,其实他找到药之后,还需要给他的婶婶送过去,所以他需要在最短的时间内找到要并且到达婶婶(‘s‘)所在的位置。
输入
    输入有多组测试数据. 每组测试数据以两个非零整数 M 和 N 开始,两者均不大于100。M 表示迷阵行数, N 表示迷阵列数。接下来有 M 行, 每行包含N个字符,不同字符分别代表不同含义: 
1) ‘@’:少年李逍遥所在的位置;
2) ‘.’:可以安全通行的方格;
3) ‘#’:有怪物的方格;
4) ‘*’:仙药所在位置。
5) ‘s‘ : 婶婶所在的位置。
    当在一行中读入的是两个零时,表示输入结束。 
输出
    对于每组测试数据,分别输出一行,该行包含李逍遥找到仙药并且送给婶婶需要穿过的最少的方格数目(计数包括初始位置的方块)。如果他不可能找到仙药, 则输出 -1。 
输入示例
8 8
.@##...#
#....#.#
#.#.##..
*.#.###.
#.#...#.
..###*#.
...#.s..
.#.*.###
0 0 
输出示例
10
其他说明
仙药的数量没有上限,所以最多有M*N-2个仙药哦~
 
 

仙岛求药