题目大意:给一个p*q的棋盘,马从(1,1)出发,求能否遍历棋盘中所有点,若能,按字典序输出路径。不能输出impossible。
题目分析:是道水回溯。但是被字典序给搞郁闷了。p代表行,q代表列,行用数字标识,列用字母标识。按字典序输出的话搜索方向很重要,方向不对搜出的路径就不是字典序了。所以方向在列上面要从-2,-1,1,2。详情请见代码:
#include <iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int N = 30;
bool flag[N][N];
int r,c;
struct node
{
int i,j;
}ans[N];
int ok;
int num;
int dir[8][2] = {{-1,-2},{1,-2},{-2,-1},{2,-1},{-2,1},{2,1},{-1,2},{1,2}};
int isok(int x,int y)
{
return (x > 0 && x <= r && y > 0 && y <= c);
}
void dfs(int curi,int curj,int deep)
{
if(ok)
return;
ans[deep].i = curi;
ans[deep].j = curj;
int i;
if(deep == r * c)
{
ok = 1;
for(i = 1;i <= deep;i ++)
{
printf("%c%d",ans[i].j + 'A' - 1,ans[i].i);
}
printf("\n");
return;
}
for(i = 0;i < 8;i ++)
{
int ti = curi + dir[i][0];
int tj = curj + dir[i][1];
if(isok(ti,tj))
{
if(!flag[ti][tj])
{
flag[ti][tj] = 1;
dfs(ti,tj,deep + 1);
flag[ti][tj] = 0;
}
}
}
}
int main()
{
int t,cas = 0;
scanf("%d",&t);
while(t --)
{
scanf("%d%d",&r,&c);
printf("Scenario #%d:\n",++cas);
memset(flag,0,sizeof(flag));
memset(ans,0,sizeof(ans));
num = 0;
flag[1][1] = 1;
ok = 0;
dfs(1,1,1);
if(ok == 0)
printf("impossible\n");
if(t)
printf("\n");
}
return 0;
}
//136K 32MS