很简单的题,不过粗心RA了很多次。就是一个DFS的题目,不过回溯的时候记得把实现不了的这一分支所做的标记“抹掉”。另外,记得是lexicographically first path(最小字典序),p, q哪个作行或列并不重要,记得p对应1,2,...而q对应A,B,...就行了。
#include<stdio.h>
#include<string.h>
#define max 27
const int jump1 = 2, jump2 = 1;
int map[max][max], path1[max], path2[max], p, q;
int Go(int row, int column, int count){
int can;
if(row<1 || row>p || column<1 || column>q)
return 0;
if( !map[row][column]){
path1[count] = row, path2[count] = column;
map[row][column] = 1;
}
else
return 0; //已经走过
if(count == p*q)
return 1;
can = Go(row-jump2, column-jump1, count+1);
if(can)
return 1;
can = Go(row+jump2, column-jump1, count+1);
if(can)
return 1;
can = Go(row-jump1, column-jump2, count+1);
if(can)
return 1;
can = Go(row+jump1, column-jump2, count+1);
if(can)
return 1;
can = Go(row-jump1, column+jump2, count+1);
if(can)
return 1;
can = Go(row+jump1, column+jump2, count+1);
if(can)
return 1;
can = Go(row-jump2, column+jump1, count+1);
if(can)
return 1;
can = Go(row+jump2, column+jump1, count+1);
if(can)
return 1;
map[row][column] = 0;
return 0; //各个方向都不行
}
int main(){
int N, can, count = 0, flag = 0;
scanf("%d", &N);
while(N--){
scanf("%d%d", &p, &q);
memset(map, 0, sizeof(map));
memset(path1, 0, sizeof(path1));
memset(path2, 0, sizeof(path2));
can = Go(1, 1, count+1);
printf("Scenario #%d:\n", ++flag);
if(can){
for(int i=1;i<=p*q;i++){
printf("%c%d", path2[i]+64, path1[i]);
}
printf("\n");
}
else
printf("impossible\n");
printf("\n");
}
return 0;
}