Problem K. 找宝箱

Problem K. 找宝箱
Time Limit: 2000ms Memory Limit: 65536kb
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 OUTPUT
3 5
1 -1 1 -1 2
0 -1 0 -1 0
0 0 0 0 0
0 0
12

分析:

宝藏数量很少, 可以先用BFS, 搜索出各宝藏,起点之间距离,然后构图,在新图上DFS搜索

出最短路径。。。

View Code
#include<stdio.h> 
#include<string.h> 
#include<stdlib.h> 
#include<iostream> 
#include<algorithm> 
#include<map> 
#include<queue> 
#include<math.h> 
using namespace std; 
 
const int inf = 0x7f7f7f7f;
int mp[110][110]; 
int G[120][120];
int visit[120][120];
int gg[120][120];
int hash[110];
int start, end, steps, sum, maxn, bao, m_bao, tt; 
int xx[ ] = {-1, 0, 0, 1}; 
int yy[ ] = {0, 1, -1, 0}; 
   
int N,M; 
   
struct node 
{ 
  int x, y,step; 
}; 
   
   
int jugde( int x, int y) 
{ 
  if( x < 1 || x > N || y < 1 || y > M ) 
      return 0; 
  return 1;     
} 
   
   
void bfs( ) 
{ 
  queue<node>q; 
  memset(visit, 0, sizeof(visit)); 
  node p; 
  p.x = start; 
  p.y = end; 
  p.step = 0; 
  q.push( p ); 
  while( !q.empty() ) 
  { 
     node px = q.front( ); 
     q.pop( ); 
     int x = px.x; 
     int y = px.y; 
     visit[x][y] = 1; 
     int dis = px.step; 
     if( mp[x][y] == 1 || mp[x][y] == 2) 
     { 
         G[gg[start][end]] [gg[x][y]] = dis;
 
     } 
     for( int i = 0; i < 4; i++) 
     { 
       int x1 = xx[i] + x; 
       int y1 = yy[i] + y; 
       if( mp[x1][y1] != -1 && jugde(x1, y1) && !visit[x1][y1] ) 
       { 
          node py; 
          py.x = x1; 
          py.y = y1; 
          py.step = dis + 1;    
          visit[x1][y1] = 1; 
          q.push( py );    
                       
       }       
             
     } 
            
  }      
        
} 
 
 
void DFS(int x, int  m, int s)
{
  
  for( int i = 1; i <= tt; i++)
    if( G[x][i] != inf && G[x][i] != 0 && !hash[i])
    {
         if( m + 1 == m_bao )
         {
            bao =  min( bao, s + G[x][i]);
         }
         hash[x] = 1;
         DFS( i , m + 1, s + G[x][i]);
         hash[x] = 0;
    }
      
}
 
 
int main( ) 
{ 
  while( scanf("%d%d", &N, &M), N + M) 
  { 
    tt=0;
    steps = 0; 
    sum = 0; 
    maxn = max( N, M );
    bao = inf;
    m_bao = 0;
    int p, q;
    memset(hash, 0, sizeof(hash));
    for( int i = 1; i <= 110; i++)
       for(int j = 1; j <= 110; j++)
               G[i][j] = ( i == j ) ? 0 : inf;
    for( int i = 1; i <= N; i++)
         for( int j = 1; j <= M; j++) 
         { 
              scanf("%d",&mp[i][j]);
              if( mp[i][j] == 1 )
              {
                  m_bao++;
                  gg[i][j] = ++tt;
              }
              if( mp[i][j] == 2 )
              {
                 p = i;
                 q = j;     
                 gg[i][j] = ++tt;
                   
              }
         }
   
    for( int i = 1;i <= N; i++)
       for( int j = 1; j <= M; j++)
       {
           if( mp[i][j] == 2 || mp[i][j] == 1 )
           {
              start = i;
              end = j;
              bfs( ); 
           }
       }
    DFS(gg[p][q], 0, 0);
    if( bao == inf )
        puts("-1");
    else
    printf("%d\n",bao);        
  } 
  return 0; 
} 
   

转载于:https://www.cnblogs.com/tangcong/archive/2012/07/16/2592979.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值