HLG 1286 迷宫与宝藏【广搜】

Description
机器人要在一个矩形迷宫里行动(不能原地停留,只能走向上///右),每移动一格花费1个单位时间。

迷宫有以下几种元素:

*机器人的起点

#墙。机器人不能走过这些格子

.平地。机器人可以在上面自由行走

0-9宝藏。当机器人走到此处会立刻获得该数字相应的宝藏,宝藏不会消失,可以反复获取(但不能停留)

若机器人要恰好获得总和为x的宝藏,它最少需要多少时间?

Input
第一行输入任务数量T,接下来有T个任务

每块第一行有两个整数, n(0 <
100), m(0 < 100),表示迷宫有n+1行和m+1

接下来n行输入迷宫

最后一行输入你要收集的宝藏的总价值x(x≤100)
Output
对于每个任务,输出最少花费的时间,如果完成不了该任务则输出-1
Sample Input
3

2 3

1.#2

#..#

*.#.

3

2 3

2.#2

#..#

*.#.

5

2 3

2.#2

#.3#

*.#.

5
Sample Output
8

-1

6

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

code:

View Code
#include<stdio.h>
#include<string.h>
#include<string.h>
#define clr(x)memset(x,0,sizeof(x))
int u[102][102][102];
char a[102][102];
int b[102][102];
int money[102][102];
int f[8]={-1,0,0,1,0,1,-1,0};
struct node
{
int x,y;
int step;
int money;
}q[1000000];
int main()
{
int i,j,t,n,m,ii,jj,si,sj,k,w,xx,yy,front,rear,ans,flag;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
clr(money); clr(b); clr(u);
for(i=0;i<=n;i++)
{
scanf("%s",a[i]);
for(j=0;j<=m;j++)
if(a[i][j]>='0'&&a[i][j]<='9')
b[i][j]=a[i][j]-'0';
else if(a[i][j]=='*')
{
si=i;
sj=j;
}
}
scanf("%d",&w);
front=rear=flag=0;
q[rear].step=0;
q[rear].x=si;
q[rear].money=0;
q[rear++].y=sj;
while(front<=rear)
{
ii=q[front].x; jj=q[front].y;
for(k=0;k<4;k++)
{
xx=ii+f[k]; yy=jj+f[k+4];

if(xx>=0&&xx<=n&&yy>=0&&yy<=m&&a[xx][yy]!='#')
{
q[rear].money=q[front].money+b[xx][yy];
if(q[rear].money>w||u[xx][yy][q[rear].money]) continue; //剪枝,如果钱大于目标钱数或该状态已达到,就不再进行扩展
q[rear].step=q[front].step+1;
if(q[rear].money==w)
{
flag=1;
ans=q[rear].step;
goto loop;
}

u[xx][yy][q[rear].money]=1;
q[rear].x=xx;
q[rear++].y=yy;
}
}
front++;
}
loop: if(w==0)printf("0\n");
else if(flag)printf("%d\n",ans);
else printf("-1\n");
}
return 0;
}

 

View Code 

#include<stdio.h>
#include<string.h>
#include<string.h>
#define clr(x)memset(x,0,sizeof(x))
int u[102][102][102];
char a[102][102];
int b[102][102];
int money[102][102];
int f[8]={-1,0,0,1,0,1,-1,0};
struct node
{
    int x,y;
    int step;
    int money;
}q[1000000];
int main()
{
    int i,j,t,n,m,ii,jj,si,sj,k,w,xx,yy,front,rear,ans,flag;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&n,&m);
        clr(money);   clr(b);  clr(u);
        for(i=0;i<=n;i++)
        {
            scanf("%s",a[i]);
            for(j=0;j<=m;j++)
                if(a[i][j]>='0'&&a[i][j]<='9')
                    b[i][j]=a[i][j]-'0';
                else if(a[i][j]=='*')
                {
                    si=i;
                    sj=j;
                }
        }
        scanf("%d",&w);
        front=rear=flag=0;
        q[rear].step=0;
        q[rear].x=si;
        q[rear].money=0;
        q[rear++].y=sj;
        while(front<=rear)
        {
            ii=q[front].x;   jj=q[front].y;  
            for(k=0;k<4;k++)
            {
                xx=ii+f[k];  yy=jj+f[k+4];  
            
                if(xx>=0&&xx<=n&&yy>=0&&yy<=m&&a[xx][yy]!='#')
                {
                    q[rear].money=q[front].money+b[xx][yy];
                    if(q[rear].money>w||u[xx][yy][q[rear].money])                        continue;      //剪枝,如果钱大于目标钱数或该状态已达到,就不再进行扩展   
                    q[rear].step=q[front].step+1;
                    if(q[rear].money==w) 
                    {
                        flag=1;
                        ans=q[rear].step;
                        goto loop;
                    }
                
                    u[xx][yy][q[rear].money]=1;
                    q[rear].x=xx; 
                    q[rear++].y=yy;
                }
            }
        front++;
        }
loop:    if(w==0)printf("0\n");
        else if(flag)printf("%d\n",ans);
        else printf("-1\n");
    }
    return 0;
}

 

 

 

posted @ 2012-03-15 12:59  'wind  阅读(224)  评论(0编辑  收藏  举报