AOJ 0558 Cheese (BFS)

题目大意:

在H * W的地图上有N个奶酪工厂,分别生产硬度为1-N的奶酪。有一只吃货老鼠准备从老鼠洞出发吃遍每一个工厂的奶酪。老鼠有一个体力值,初始时为1,每吃一个工厂的奶酪体力值增加1(每个工厂只能吃一次),且老鼠只能吃硬度不大于当前体力值的奶酪。 

老鼠从当前格走到相邻的无障碍物的格(上下左右)需要时间1单位,有障碍物的格不能走。走到工厂上时即可吃到该工厂的奶酪,吃奶酪时间不计。问吃遍所有奶酪最少用时。 

输入:第一行三个整数H(1 <= H <= 1000)、W(1 <= W <=1000)、N(1 <= N <= 9),之后H行W列为地图, “.“为空地, ”X“为障碍物,”S“为老鼠洞, 1-N代表硬度为1-N的奶酪的工厂。

此题依次吃奶酪即可。

先找到起点到奶酪1的最小步数,再以奶酪1为起点找到奶酪2的最小步数......最后把他们加起来即可。

此题还有个需要注意的是对于大于自己体力的奶酪所在的区域,不是不能过,而是能过,但是不能吃奶酪,过而不吃。

#include <iostream>
#include <queue>
#include <cstdio>
#include <cstring>
using namespace std;

char ma[1005][1005];
int vis[1005][1005];
int n,m,t,ax,ay,c;
struct node
{
    int x,y,ti;//位置及时间
    node(int a,int b,int c){x=a;y=b;ti=c;}
};

int dx[]={-1,0,1,0};
int dy[]={0,1,0,-1};

int bfs(int xx,int yy)
{
    memset(vis,0,sizeof(vis));
    queue<node> que;
    que.push(node(xx,yy,0));
    vis[xx][yy]=1;
    while(!que.empty())
    {
        node tem=que.front();
        que.pop();
        //vis[tem.x][tem.y]=0;
        for(int i=0;i<4;i++)
        {
            if(tem.x+dx[i]>=0&&tem.x+dx[i]<n&&tem.y+dy[i]>=0&&tem.y+dy[i]<m)//没越界
            {
                int x=tem.x+dx[i];
                int y=tem.y+dy[i];
                if(vis[x][y])continue;//如果这个点在经历过则换个方向
                if(c==ma[x][y]-'0')//如果下一个是终点的话直接返回
                {
                    ax=x;ay=y;
                    return tem.ti+1;
                }
                if(ma[x][y]=='X')continue;//如果是墙的话,那么只能换个方向

                else//放入队列就好了
                     que.push(node(x,y,tem.ti+1));
                vis[x][y]=1;

            }
        }
    }
}

int main()
{
    freopen("1.txt","r",stdin);
    while(cin>>n>>m>>t)
    {
        memset(vis,0,sizeof(vis));
        for(int i=0;i<n;i++)
        {
            scanf("%s",&ma[i]);
            for(int j=0;j<m;j++)
                if(ma[i][j]=='S')
            {
                ax=i;ay=j;
            }
        }
        int ans=0;
        for(int i=1;i<=t;i++)
        {
            c=i;
            ans+=bfs(ax,ay);
            //cout<<ans<<endl;
        }

        cout<<ans<<endl;


    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值