路线可能有多条,线路要求输出的是按字典序搜索出现的第一个路线;也就是要从(1,1)开始;
思路:从(1,1)点开始,直接深搜八个方向,注意方向的优先顺序;直接搜索就可以;
编程要细心,如将==写成=导致调试一个多小时,此类错误以后务必杜绝!
#include <iostream> #include <string> #include <cstdio> using namespace std; int map[30][30],c,r,num;//最大的行数、列数和已遍历点数 string ans; //教训由于一个==写成=号而调试近一个小时!吸取教训,细心再细心! int dfs(int i,int j){ if (map[i][j]) return 0;//该点已经访问过,返回 num++; ans+=i; ans+=j;//这是字符串的赋值操作,将坐标记录在ans中,奇数位为行标,偶数位为列标 map[i][j] = 1; if (num == r*c) return 1;//所有点已经遍历完毕 if(i-2>=1&&j-1>=1&&dfs(i-2,j-1)) return 1;//关于越界的判断可以简化,若加判上界,若减判下界 else if(i-2>=1&&j+1<=c&&dfs(i-2,j+1)) return 1; else if(i-1>=1&&j-2>=1&&dfs(i-1,j-2)) return 1; else if(i-1>=1&&j+2<=c&&dfs(i-1,j+2)) return 1; else if(i+1<=r&&j-2>=1&&dfs(i+1,j-2)) return 1; else if(i+1<=r&&j+2<=c&&dfs(i+1,j+2)) return 1; else if(i+2<=r&&j-1>=1&&dfs(i+2,j-1)) return 1; else if(i+2<=r&&j+1<=c&&dfs(i+2,j+1)) return 1; //如果所有方向都无法深入搜索则回溯 ans.resize(ans.size()-2);//回溯,去掉上一次的访问记录 map[i][j] = 0; num--; return 0; } int main(){ long caseNum,i=0; cin>>caseNum; while(caseNum--){ i++; cout<<"Scenario #"<<i<<":"<<endl; num = 0; memset(map,0,sizeof(map));//快速赋值 ans = ""; cin>>c>>r; if(dfs(1,1)){ for (int j=0;j<ans.size();j++) { if (j%2) { ans[j]+='0'; } else ans[j]+='A'-1; } cout<<ans<<endl<<endl; } else cout<<"impossible"<<endl<<endl; } return 0; }