找宝箱

Problem Description

作为一个强迫症患者,小 Y 在走游戏里的迷宫时一定要把所有的宝箱收集齐才肯罢休。现在给你一个 N *M 的迷宫,里面有障碍、空地和宝箱,小 Y 在某个起始点,每一步小 Y 可以往上下左右走,当然前提时没有走出迷宫并且走到的点不是障碍。如果小 Y 走到了某个为宝箱的点,那么这个宝箱就被他收集到了,然后此处变为空地。 现在你需要计算小 Y 最少需要走多少步才能收集齐所有的宝箱。

Input

输入包含多组数据。 对于每组数据,第一行两个正整数 N;M(1<=N;M<=100),表示迷宫大小。 接下来 N 行,每行 M 个整数,第 i + 1 行的第 j 个整数表示迷宫第 i 行第 j 列的情况,0 表示空地,-1表示障碍,1 表示宝箱,2 表示小Y 的起始点。保证2 只有一个,且宝箱数量不超过5 个。 数据以两个0 表示结尾。

Output

对于每组数据输出一行,包含一个整数,表示小 Y 最少的步数。如果小 Y 无法收集齐所有宝箱,输出-1。

Sample Input

3 5
1 -1 1 -1 2
0 -1 0 -1 0
0 0 0 0 0
0 0
#include<iostream>
#include<queue>
#include<string.h>
#include<algorithm>
using namespace std;
int map[105][105];
int ss[105][105];
int sr[8][8];
int m,n,cnt;
int dir[4][2]={{0,-1},{1,0},{0,1},{-1,0}};
bool isarea(int x,int y)
{
 return x>=0&&x<m&&y>=0&&y<n;
}
struct ff{
 int x;
 int y;
};
ff f1[8];
struct lmx{
 int x;
 int y;
 int step;
};
int bfs(int e,int w)
{
   queue<lmx>q;
   while(!q.empty()) q.pop();
   int i,j;
   for(i=0;i<m;i++)
   {
    for(j=0;j<n;j++)
    {
     map[i][j]=ss[i][j];
    }
   }
   lmx s1,s2,s3;
   s1.x=f1[e].x;
   s1.y=f1[e].y;
   s1.step=0;
   q.push(s1);
   map[s1.x][s1.y]=-1;
   while(!q.empty())
   {
      s2=q.front();
   q.pop();
      for(i=0;i<4;i++)
   {
          s3.x=s2.x+dir[i][0];
    s3.y=s2.y+dir[i][1];
    if(map[s3.x][s3.y]!=-1&&isarea(s3.x,s3.y))
    {
       s3.step=s2.step+1;
                 q.push(s3);
     map[s3.x][s3.y]=-1;
      if(f1[w].x==s3.x&&f1[w].y==s3.y) return s3.step;
    }
   }
   }
   return -1;
}
int main()
{
     int i,j,flag,sum,ce;
     char sp[7]={"012345"};
  while(cin>>m>>n)
  {
   cnt=1;
   ce=10000;
   sum=0;
   flag=0;
   if(m==0&&n==0) break;
   for(i=0;i<m;i++)
   {
    for(j=0;j<n;j++)
    {
     cin>>ss[i][j];
     if(ss[i][j]==2)  {f1[0].x=i;f1[0].y=j;}
     if(ss[i][j]==1)  {f1[cnt].x=i;f1[cnt].y=j;cnt++;}
    }
   }
   memset(sr,0,sizeof(sr));
   for(i=0;i<cnt;i++)
   {
    for(j=0;j<cnt;j++)
    {
     if(i!=j) sr[i][j]=bfs(i,j);
     if(sr[i][j]<0) { flag=1;break;}
    }
    if(flag) break;
   }
   if(flag)cout<<"-1"<<endl;
   else
   {
    do{
     sum=0;
     for(i=0;i<cnt-1;i++)
     {
        sum+=sr[sp[i]-'0'][sp[i+1]-'0'];
     }
     if(sum<ce) ce=sum;
    }while(next_permutation(sp+1,sp+cnt));
    cout<<ce<<endl;
   }
  }
 return 0;
}
posted @ 2013-03-29 09:12  forevermemory  阅读(409)  评论(0编辑  收藏  举报