算法基础.简单迷宫

手机的诱惑

Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 32768/32768K (Java/Other)
Total Submission(s) : 39   Accepted Submission(s) : 21
Font: Times New Roman | Verdana | Georgia
Font Size: ← →

Problem Description

张晨乐在一个古老的迷宫中发现了一个手机,这个手机深深地吸引了他。

然而,当他拾起手机,迷宫开始摇晃,张晨乐能感觉到地面下沉。他意识到:这个手机只是一个诱饵!于是,他不顾一切地试图冲出这个迷宫。

迷宫是一个大小为N*M的矩形,有一扇门,一开始,门是关闭的,并在第T秒打开一瞬间(小于1秒的时间)。因此,张晨乐必须刚好在第T秒钟到达门口。
每一秒,他都可以向上,下,左,右四个相邻的位置中的任意一个移动。一旦他进入一个新的地方,这个地方的地面就会开始下沉,并在下一秒消失。因此,他不能在一个地方停留超过一秒钟,也不能再进入曾经走过的地方。

请问,可怜的张晨乐能够逃出迷宫吗?

Input

输入由多个测试用例组成。
每个测试用例的第一行包含三个整数N,M和T(1 <N,M <7; 0 <T <50),分别表示迷宫的大小和门打开的时间。
接下来的N行给出迷宫布局,每行包含M个字符。

每个字符含义如下:

'X':不能进入的墙
'S':起点
'D':门
'.':可以行走的地方

输入以三个0结束,这个测试用例不被处理。




#include<bits/stdc++.h>

using namespace std;
char Map[9][9];
int n,m,t,di,dj;
bool escape;
int dir[4][2]={{0,-1},{0,1},{1,0},{-1,0}};
void dfs(int si,int sj,int cnt)
{
 int i,temp;
 if(si>n||sj>m||si<=0||sj<=0)
 return;  
 if(cnt==t&&si==di&&sj==dj)
 escape=1;
 if(escape)
 return;
 temp=(t-cnt)-abs(si-di)-abs(sj-dj);
 if(temp<0||temp%2==1)
 return;
 for(i=0;i<4;i++)
 {
  if(Map[si+dir[i][0]][sj+dir[i][1]]!='X')
  {
   Map[si+dir[i][0]][sj+dir[i][1]]='X';
   dfs(si+dir[i][0],sj+dir[i][1],cnt+1);
   Map[si+dir[i][0]][sj+dir[i][1]]='.';    
  }    
 }    
}
int main()
{
 int i,j,si,sj;
 while(cin>>n>>m>>t)
 {
  if(n==0&&m==0&&t==0)
  break;
  int wall=0;
  for(i=1;i<=n;i++)
  {
   for(j=1;j<=m;j++)
   {
    cin>>Map[i][j];
    if(Map[i][j]=='S')
    {
     si=i;
     sj=j;    
    }
    else if(Map[i][j]=='D')
    {
     di=i;
     dj=j;    
    }
    else if(Map[i][j]=='X')
    wall++;    
   }    
  }
  if(n*m-wall<=t)
  {
   cout<<"NO"<<endl;
   continue;    
  }
  escape=0;
  Map[si][sj]='X';
  dfs(si,sj,0);
  if(escape)
  cout<<"YES"<<endl;
  else
  cout<<"NO"<<endl;    
 }
 return 0;    
} 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值