递归函数中为什么最后有一个 =false?
这个问题一开始我胡思乱想了很多,请教了大佬,在自己也想了想,其实答案就只是:要把它标记为false,因为别的路径可能还会访问到它
这种写法在大佬看来是要超时的,没有超时的原因在于深色高亮部分代码: if(step>min) return;
另外,将下面代码注视部分封印解除,可以看到“一部分”代码走过的“弯路”
推荐测试用例:
5 4
XX
X X
X
X
5 1 4 4
0 0 0 0
5 4
XXXXX
X X
XXX X
XXX
2 3 5 3
1 3 4 4
2 3 3 4
0 0 0 0
0 0
AC代码:
#include<iostream>
#include<cstring>
#define maxn 75+2
#define min MIN //min与预定义函数重名...
using namespace std;
int to[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
int i,j;
bool mark[maxn][maxn]; //标记格子是否走过
char map[maxn][maxn];
int x1,x2,y1,y2; //x1,y1起点 x2,y2终点
int w,h,min;
void search(int x1,int y1,int x2,int y2,int step,int f){ //递归遍历
if(step>min) return;
if(x1 == x2 && y1 == y2){ //已经到了终点
if(min > step) //更新min 或 返回上一层递归
min = step;
return;
}
for(int i=0; i<4 ; i++){ //向四个方向遍历
int x = x1+to[i][0]; //下一步走x,y
int y = y1+to[i][1];
// x,y在边界内 且( x,y处无卡牌 而且未走过 或 x,y已经到达终点,终点有卡牌 )
if( (x>-1) && (x<w+2) && (y>-1) && (y<h+2) && (((map[y][x]==' ') && (mark[y][x]==false)) || ((x==x2) && (y==y2) && (map[y][x] == 'X'))) ){ //x,y是否合法
mark[y][x] = true; //x,y合法,给一个走过的标记
if(f == i) search(x,y,x2,y2,step,i); //未转向 step不变
else search(x,y,x2,y2,step+1,i); //转向 step+1
// for(i=0;i<=h+1;i++){
// for(j=0;j<=w+1;j++){
// if(mark[i][j]==true)
// putchar('x');
// else putchar('0');
// cout<<' ';
// }
// cout<<endl;
// }
// cout<<endl;
mark[y][x] = false; //看不懂
}
}
}
int main(){
freopen("in.txt","r",stdin);
int count=0,game=0;
while( scanf("%d %d",&w,&h)==2 && w!=0 ){
count=0;
game++;
printf("Board #%d:\n",game);
for(i=1;i<=h;i++){
getchar();
for(j=1;j<=w;j++){
map[i][j]=getchar();
map[0][j]=' ';
map[h+1][j]=' ';
}
map[i][0]=' ';
map[i][w+1]=' ';
}
map[0][0]=' ';map[0][w+1]=' ';map[h+1][0]=' ';map[h+1][w+1]=' ';
// memset(mark,false,sizeof(mark)); //要不要都行
while(scanf("%d %d %d %d",&x1,&y1,&x2,&y2) && x1>0){
count++;
min=100000;
search(x1,y1,x2,y2,0,-1);
if( min<10000 )
printf("Pair %d: %d segments.\n",count,min);
else
printf("Pair %d: impossible.\n",count);
}
printf("\n");
}
return 0;
}