深度搜索,注意要剪枝
1.奇偶剪枝
可以把map看成这样:
0 1 0 1 0 1
1 0 1 0 1 0
0 1 0 1 0 1
1 0 1 0 1 0
0 1 0 1 0 1
从为 0 的格子走一步,必然走向为 1 的格子
从为 1 的格子走一步,必然走向为 0 的格子
即:
0 ->1或1->0 必然是奇数步
0->0 走1->1 必然是偶数步
则如果((di-si+dj-sj)&1)!=(t&1) 就可以直接输出“NO”了
2.判断可走的block是否小于时间总数
n*m-wall<=t 就输出“NO”
#include <iostream>
#include <stdio.h>
using namespace std; char map[][];
int desc[][]={{-,},{,},{,},{,-}};
int si,sj,di,dj;
int n,m,t;
int escape; void dfs(int ni,int nj,int nt)
{
if(escape) return;
if(nt>t) return;
else if(nt==t)
{
if(ni==di && nj==dj)
{
printf("YES\n");
escape=;
}
return;
}
else
{
for(int k=;k<;++k)
{
if(ni+desc[k][]>-&&ni+desc[k][]<n && nj+desc[k][]>-&&nj+desc[k][]<m)
{
if(map[ni+desc[k][]][nj+desc[k][]]!='X')
{
map[ni][nj]='X';
//printf("goto (%d,%d) %d\n",ni+desc[k][0],nj+desc[k][1],nt+1);
dfs(ni+desc[k][],nj+desc[k][],nt+);
map[ni][nj]='.';
}
}
}
}
} int main()
{
int i,j,wall; while(scanf("%d %d %d",&n,&m,&t),n||m||t)
{
escape=;
di=;
dj=;
wall=;
getchar();
for(i=;i<n;++i)
{
for(j=;j<m;++j)
{
//scanf("%c",&map[i][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;
}
//getchar();
} //前半句是判断可以走的block数是否小于等于时间;
//后半句是奇偶剪枝
if(n*m-wall<=t || ((di-si+dj-sj)&)!=(t&))
{
printf("NO\n");
continue;
}
dfs(si,sj,);
if(escape==) printf("NO\n");
}
}