题目:
HDU - 1010 |
但是只用搜索的话 提交就 TLE
今天做这道题纠结了一个下午,最后终于solve了呵呵
这题用到了奇偶剪枝
奇偶剪枝就是把一张地图看成01交错而成的图,对于都在1或零处的起点和中点 ,必须经过偶数部才能从起点到终点;
剪枝1:如果指定的步数为奇数,必定不能到达终点直接剪去
定义一个变量num来存储该状态到终点的最小步数,num=abs(x-x2)+abs(y-y2); x2,y2 为终点坐标 。总数为k,当前步数为step
如果k-step-num<0则剪去
令p=k-step-num;p的含义是 从该点到终点超出最小步数的步数 ,必定是偶数时才成立
剪枝2:if(P<0||P%2!=0)return 0;
剪枝3:如果地图中可走的步数少于 k,则不可能成立,直接输出NO,剪去。
代码如下:
#include<stdio.h>
#define N 10
char a[N][N];
int n,m,k;
int count;
int x1,y1,x2,y2;
int dx[4]={0,0,1,-1};
int dy[4]={1,-1,0,0};
int abs(int x)
{
return x>0?x:-x;
}
int dfs(int x,int y,int step)
{
if(step>k)return 0;
if(step==k&&x==x2&&y==y2)return 1;
int num=abs(x2-x)+abs(y2-y);
int p=k-step-num;
if(p>=0&&p%2==0)
{
int i;
for(i=0;i<4;i++)
{
int xx=x+dx[i];
int yy=y+dy[i];
if(xx<0||yy<0||xx>=n||yy>=m)
continue;
if(a[xx][yy]=='X')
continue;
a[x][y]='X';
if(dfs(xx,yy,step+1))return 1;
a[x][y]='.';
}
}
return 0;
}
int main()
{
int i,j;
while(scanf("%d%d%d",&n,&m,&k)!=EOF){
count=0;
if(n==0&&m==0&&k==0)break;
for(i=0;i<n;i++)
scanf("%s",a[i]);
for(i=0;i<n;i++)
for(j=0;j<m;j++)
{
if(a[i][j]=='S')
x1=i,y1=j;
if(a[i][j]=='D')
x2=i,y2=j;
if(a[i][j]=='.')
count++;
}
if(count+1<k){printf("NO\n");continue;}
if((x1+y1+x2+y2+k)%2!=0){printf("NO\n"); continue;}
if(dfs(x1,y1,0))printf("YES\n");
else printf("NO\n");
}
}