AOJ0558——Cheese(BFS)


题目链接

       题目大致是想说有一只生物想吃cheese,然后有n个工厂生产cheese(1<=n<=9),且每个工厂生产起司的消耗量均不一样,刚好有n个工厂,而这只生物只能吃消耗量小于或等于它自己体力的cheese且它在每个工厂吃且只吃一次,其初始体力为1,问从出发点是S开始,如何在最少的步数内吃到所有的cheese,当然,移动方式就是上下左右。题目意思已经很明确了,就是图上的'X'表示障碍物不能走,数字一定是从1~n,而你的初始体力为1,所以你就只能老老实实的从起点S开始找1,再找2........,最后是n。(工厂均用数字表示,且保证每个工厂是一定能访问到的)然后对每一次查找都用BFS,还有没查找到一次都要将地图重新初始化,不然,以前走过的都无法再走了,题目是保证有解的。


#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<queue>

using namespace std;

char s[1005][1005]= {'\0'};

int n, m, num;
int a[10][2]= {0};

int mov1[4]= {-1,0,1,0};
int mov2[4]= {0,1,0,-1};

struct node
{
    int x;
    int y;
    int ans;
    node()
    {
        x=0;
        y=0;
        ans=0;
    }
    node(int a,int b,int c)
    {
        x=a;
        y=b;
        ans=c;
    }
};

queue<node>q;

node t;

void bfs(node temp,int type)
{
    if(type>num)return;
    if(a[type][0]==temp.x&&a[type][1]==temp.y)
    {
            //printf("type is %d\n",type);
            for(int i=1; i<=n; i++)
                for(int j=1; j<=m; j++)
                    if(s[i][j]=='*')
                        s[i][j]='.';
            while(!q.empty())q.pop();
            bfs(temp,type+1);
    }
    else
    {
        q.push(temp);
        while(!q.empty())
        {
            t=q.front();
            q.pop();
            if(a[type][0]==t.x&&a[type][1]==t.y)
            {
                bfs(t,type);
                break;
            }
            s[t.x][t.y]='*';
            for(int i=0;i<4;i++)
            {
                int tx=t.x+mov1[i];
                int ty=t.y+mov2[i];
                if(tx<1||ty<1||tx>n||ty>m||s[tx][ty]=='X'||s[tx][ty]=='*')continue;
                node p(tx,ty,t.ans+1);
                s[tx][ty]='*';
                //printf("jiezhi %d %d %d\n",tx,ty,t.ans+1);
                q.push(p);
            }
        }

    }
}

int main()
{
    //freopen("in.in","r",stdin);
    while(scanf("%d%d%d",&n,&m,&num)!=EOF)
    {
        char c=getchar();
        memset(s,'\0',sizeof(s));
        memset(a,0,sizeof(a));
        int x=0, y=0;
        for(int i=1; i<=n; i++)
        {
            for(int j=1; j<=m; j++)
            {
                scanf("%c",&s[i][j]);
                if(s[i][j]=='S')
                {
                    x=i;
                    y=j;
                }
                if(s[i][j]>='0'&&s[i][j]<='9')
                {
                    a[s[i][j]-'0'][0]=i;
                    a[s[i][j]-'0'][1]=j;
                }
            }
            c=getchar();
        }
        //for(int i=1;i<=num;i++)
        //    printf("%d %d\n",a[i][0],a[i][1]);
        while(!q.empty())q.pop();
        /*for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=m;j++)
                printf("%c",s[i][j]);
            printf("\n");
        }*/
        node temp;
        temp.x=x;
        temp.y=y;
        bfs(temp,1);
        printf("%d\n",t.ans);
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值