POJ 2488
题意:给一个n*m的国际象棋棋盘 问一个马能否不重复走完全部格子 如果有输出字典序最小的路径 行为数字 列为字母 一个格子的坐标为(列字母,行数字)要求字典序最小所以在每次马的行走时 走字典序最小的那一个
wa了两发 没注意到数组的大小 n*m <= 26 所以n,m <= 26 太坑爹!
#include <cstdio>
#include <iostream>
#include <cstring>
#include <queue>
#include <vector>
#define sf scanf
#define pf printf
using namespace std;
const int step[][2] = { {-1,-2} ,{1,-2} ,{-2,-1} ,{2,-1} , {-2,1} , {2,1} , {-1,2} , {1,2} }; //马的step 按字典序排列
const int maxn = 100;
bool vis[maxn][maxn];
int n,m;
int vis_cnt;
vector<int> ans;
bool DFS(int row,int col){
vis[row][col] = 1;
vis_cnt++;
if(vis_cnt == n * m){
ans.push_back(row);
ans.push_back(col);
return true;
}
for(int i = 0;i < 8;++i){
int nrow = row + step[i][0],ncol = col + step[i][1];
if(nrow >= 0 && nrow < n && ncol >= 0 && ncol < m && !vis[nrow][ncol]){
if( DFS(nrow,ncol) ){
ans.push_back(row);
ans.push_back(col);
return true;
}
}
}
vis_cnt--;
vis[row][col] = 0;
return false;
}
int main(){
int T,ca = 0;
sf("%d",&T);
while( T-- ){
sf("%d%d",&n,&m);
bool ANS = false;
memset(vis,0,sizeof(vis));
vis_cnt = 0;
ans.clear();
for(int j = 0;j < m && !ANS;++j){
for(int i = 0;i < n && !ANS;++i){
if(DFS(i,j)){
ANS = true;
}
}
}
pf("Scenario #%d:\n",++ca);
if(ANS){
for(int i = ans.size() - 1;i >= 0;i -= 2){
pf("%c%d",ans[i] + 'A',ans[i - 1] + 1);
}
pf("\n");
}
else pf("impossible\n");
pf("\n");
}
return 0;
}