poj2312题解

来源:http://poj.org/problem?id=2312

思路:这道题可以用BFS进行解答,遇到E需要走两步,而遇到B要先打掉B再走,可以看作需要走两步。但与普通的BFS不同,这里的点可以重复进队列,类似于spfa,不断修改点上的步数,最后得到最优解。

代码:

#include <stdio.h>
int g[301][301],f[301][301],f1[301][301];

//f数组用来判断点是否在队列中,f1数组用来储存到达点的最少步数

struct rec{
    int x,y;
}q[100000];
const int fx[4]={0,0,1,-1};
const int fy[4]={1,-1,0,0};
int n,m,sx,sy,tx,ty,s,t,x1,y1,x,y;

int doing(void)
{
    s=0;t=1;q[1].x=sx;q[1].y=sy;
    f[sx][sy]=1;f1[sx][sy]=0;
    while(s<t)
    {
        s++;
        x=q[s].x;y=q[s].y;
        f[x][y]=0;
        for(int i=0;i<4;i++)
        {
            x1=x+fx[i];y1=y+fy[i];
            if(1<=x1&&x1<=n&&1<=y1&&y1<=m&&g[x1][y1]!=-1)
            {
                if(f1[x1][y1]>f1[x][y]+g[x1][y1])
                {
                    f1[x1][y1]=f1[x][y]+g[x1][y1];
                    if((x1!=tx||y1!=ty)&&f[x1][y1]==0)
                    {
                        t++;
                        q[t].x=x1;q[t].y=y1;
                        f[x1][y1]=1;
                    }
                }
            }
        }
    }
    if(f1[tx][ty]==1000000000) printf("-1\n");
    else printf("%d\n",f1[tx][ty]);
    return 0;
}

int main()
{
    char c;
    scanf("%d%d\n",&n,&m);
    while(n!=0&&m!=0)
    {
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=m;j++)
            {
                scanf("%c",&c);
                f[i][j]=0;
                f1[i][j]=1000000000;
                if(c=='Y')
                {
                    sx=i;sy=j;
                    g[i][j]=1;
                }
                if(c=='T')
                {
                    tx=i;ty=j;
                    g[i][j]=1;
                }
                if(c=='S') g[i][j]=-1;
                if(c=='E') g[i][j]=1;
                if(c=='B') g[i][j]=2;
                if(c=='R') g[i][j]=-1;
            }
            scanf("\n");
        }
        doing();
        scanf("%d%d\n",&n,&m);
    }
    return 0;
}




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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值