來源:點擊打開鏈接
看上去數據規模很小,但是必須要剪枝,否則直接爆TLE。
通過這個題可以練習奇偶剪枝。
另外:還有一個優化方式,如果所有步數走完了門還沒關,則直接返回結果"NO".
#include <iostream>
#include <cstring>
#include <cmath>
#include <cstdlib>
using namespace std;
int n,m,tarstep;
int tari,tarj;
int si,sj;
char map[10][10];
int dir[4][2]={0,1,0,-1,1,0,-1,0};
int ok=0;
void dfs(int si,int sj,int step)
{
int temp;
if(si>n || sj>m || si<=0 || sj<=0)
return;
if(step==tarstep && si==tari && sj==tarj)
ok=1;
if(ok==1)
return;
//奇偶剪枝
temp=(tarstep-step)-abs(si-tari)-abs(sj-tarj);
if(temp<0 || temp&1)
return;
for(int 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],step+1);
map[si+dir[i][0]][sj+dir[i][1]]='.';
}
}
return ;
}
int main()
{
while(cin>>n>>m>>tarstep)
{
if(n==0 && m==0 && tarstep==0)
break;
int wall=0;
for(int i=1;i<=n;i++) //下標從1開始
{
for(int j=1;j<=m;j++)
{
cin>>map[i][j];
if(map[i][j]=='S')
{
si=i;
sj=j;
}
else if(map[i][j]=='D')
{
tari=i;
tarj=j;
}
else if(map[i][j]=='X')
wall++;
}
}
if(n*m-wall<tarstep) //剪枝,如果能走的空地走完門沒開
{
cout<<"NO"<<endl;
continue;
}
ok=0;
map[si][sj]='X'; //初始化破壞掉
dfs(si,sj,0);
if(ok==0)
{
cout<<"NO"<<endl;
}
else
{
cout<<"YES"<<endl;
}
}
return 0;
}