初看这题,感觉很简单, 结果一直超时, 添了剪枝1, 发现需要仍然超时, 上网搜了下, 加了剪枝2,结果仍然超时, 原来这个题是经典的奇偶剪枝……
将剪枝3添上以后,惊奇地发现WR了, 怎嘛可能……纠结了很久, 在网上发现一个结题报告说这个不能单个的输入字符!! 修改了下, 果断AC了……还有, 我今天突然发现函数 abs()竟然不在头文件math.h下, 而是在stdlib.h下……
#include<stdio.h> #include<math.h> #include<stdlib.h> int n, m, t, map[8][8]; int a[4][2]={{-1,0},{1,0},{0,-1},{0,1}}; int DFS(int num, int x, int y, int ex, int ey) { if( num==t && x==ex && y==ey) return 1; if( num>=t ) return 0;//若在t时间未到达,剪枝 if(t-num<(abs(ex-x)+abs(ey-y)) )return 0;//剪枝2:需要的时间比理论上的最短时间还小 if( (t-num-(abs(ex-x)+abs(ey-y)))%2!=0 ) return 0;// 剪枝3:比理论上的最短距离多出来的必是偶数 int i, x1, y1; for(i=0; i<4; i++) { x1=x+a[i][0]; y1=y+a[i][1]; if(x1>=0&&x1<m && y1>=0&&y1<n && map[y1][x1]) { map[y1][x1]=0; if( DFS( num+1, x1, y1, ex, ey)) return 1; map[y1][x1]=1; } } return 0; } int main() { int sx, sy, ex, ey; int i, j; char str[8]; while( scanf("%d %d %d", &n, &m, &t) &&(n+m+t)!=0) { for(i=0; i<n; i++) { scanf("%s", str); for(j=0; j<m; j++) { map[i][j]=0; if(str[j]=='S') { sx=j;sy=i; } else if(str[j]=='D') { ex=j;ey=i;map[i][j]=1; } else if(str[j]=='.') map[i][j]=1; } } if( DFS(0, sx,sy, ex,ey) ) printf("YES\n"); else printf("NO\n"); } }