王道机试指南 例题9.3 Knight's Journey
题目:
题目大意:
日字规则:
这个棋字的行走规则是“日”字,就是说它可以跳到“日”字对角线的位置,如果有对方的棋字,那么就可以“吃”掉。如下图,黄色是自己的马,那么绿色就是可以行走的位置。
算法及思路:
代码:
#include <iostream>
#include <string>
#include <cstring> //memset函数的头文件
using namespace std;
const int MAXN=30;
int p,q;
bool visit[MAXN][MAXN];
int direction[8][2]={{-1,-2},{-1,2},{1,-2},{1,2},{-2,1},{-2,-1},{2,1},{2,-1}};//保存日字规则下下一步的八种走法
bool DFS(int x,int y,int step,string ans){//深度优先搜索
if(step==p*q){//如果当前步数==p*q,则搜索成功
cout<<ans<<endl;
cout<<endl;
return true;
}
else{//否则继续搜索
for(int i=0;i<8;i++){//依次将日字规则下下一步的八种情况按深度优先搜索规则进行遍历
int nx=x+direction[i][0];
int ny=y+direction[i][1];
char col=ny+'A';//列号
char row=nx+'1';//行号
if(nx<0 || nx>=p || ny<0 || ny>=q || visit[nx][ny]==1)//如果下一步走出棋盘边界或已经走过,则讨论下一种情况
continue;
visit[nx][ny]= true;//标记位置
if(DFS(nx,ny,step+1,ans+col+row)==1)//如果遍历成功则返回
return true;
else//否则取消标记
visit[nx][ny]=false;
}
}
return false;
}
int main(){
int n;
cin>>n;
int caseNum=1;
for(int i=0;i<n;i++){
cin>>p>>q;
memset(visit,false, sizeof(visit));
cout<<"Scenario #"<<caseNum++<<":"<<endl;
visit[0][0]=true;//标记设置A1位置为访问过
if(DFS(0,0,1,"A1")==0) {//深度优先搜索
cout << "impossible" << endl;
cout<<endl;
}
}
return 0;
}
运行结果:
查看20道真题和解析
