B - A Knight's Journey
题目翻译
背景
这位骑士厌倦了一遍又一遍地看到相同的黑白方块,于是决定开始一段旅程世界各地。每当一个骑士移动,它是一个方向上的两个正方形和一个垂直的正方形。骑士的世界是他生活的棋盘。我们的骑士生活在一个棋盘上,它的面积比普通的8×8棋盘小,但它仍然是长方形的。你能帮助这个冒险骑士制定旅行计划吗?
问题
找到一条路,让骑士拜访每一个广场一次。骑士可以在棋盘的任何一个正方形上开始和结束。
找到一条路,让骑士拜访每一个广场一次。骑士可以在棋盘的任何一个正方形上开始和结束。
输入
输入第一行以正整数N开头。下面几行包含N个测试用例。每个测试用例由一行包含两个正整数P和Q,例如1<=P*Q<=26。这代表了一个p*Q棋盘,其中P描述了有多少不同的平方数字1,……,P存在,Q描述了多少不同的平方字母存在。这些是拉丁字母的第一个Q字母:a,…
输入第一行以正整数N开头。下面几行包含N个测试用例。每个测试用例由一行包含两个正整数P和Q,例如1<=P*Q<=26。这代表了一个p*Q棋盘,其中P描述了有多少不同的平方数字1,……,P存在,Q描述了多少不同的平方字母存在。这些是拉丁字母的第一个Q字母:a,…
输出
每个场景的输出以包含“场景#I:”的行开始,其中我是从1开始的场景的数量。然后打印一个单行,包含字典的第一路径,访问所有方块的棋盘骑士与行动后一个空线。路径应该通过连接被访问的方块的名称在一条线上给出。每个方名由大写字母和数字组成。如果没有这样的路径存在,那么您应该在一行中输出不可能。
Sample Input
每个场景的输出以包含“场景#I:”的行开始,其中我是从1开始的场景的数量。然后打印一个单行,包含字典的第一路径,访问所有方块的棋盘骑士与行动后一个空线。路径应该通过连接被访问的方块的名称在一条线上给出。每个方名由大写字母和数字组成。如果没有这样的路径存在,那么您应该在一行中输出不可能。
Sample Input
3 1 1 2 3 4 3Sample Output
Scenario #1: A1 Scenario #2: impossible Scenario #3: A1B3C1A2B4C2A3B1C3A4B2C4
马走日,遍历整个图,使它字典序最小,abc一个字典序,aca两个字典序,应该尽量先走上面一行,尽量走左边,这样字典序最小
bfs
bfs
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <algorithm> using namespace std; //马走日可以走的八个方向 八个方向是有顺序的,为了得到最小字典序 int s[8][2]={{-2, -1}, {-2, 1}, {-1, -2}, {-1, 2},{1, -2}, {1, 2}, {2, -1}, {2, 1}}; int a[1001][2],c[30][30]; int z,sum; int n,m;//n行m列 int ss(int x,int y) { if(x<1||y<1||x>m||y>n) return 0; return 1; }//判断是否在边界内 int bfs(int x,int y) { a[sum][0]=x;//0为字符 a[sum][1]=y;//1为数字 if(sum==n*m)//判断是否全部访问过 { z=1;//全部访问做标记z return 0; } int i,j; int ii,jj; for(i=0;i<8;i++) { ii=x+s[i][0];//横坐标移动 得到新的横坐标 jj=y+s[i][1];//纵坐标移动 得到新的纵坐标 if(ss(ii,jj)==1&&c[ii][jj]==0)//ss(ii,jj)==1在边界内 c[ii][jj]==0没被访问 { c[ii][jj]=1;//访问标记 sum++;//记录访问过的格子数 bfs(ii,jj); if(z==1) return 0;//全部访问完并有通路,结束 gg(int x,int y)=0 sum--;// 中途无通路需要返回 并消除标记 c[ii][jj]=0;//消除标记 } } return 1; } int main () { int T,b=0;//b第几个案列 cin>>T; while(T--) { b++; //b第几个案列 cin>>n>>m;//n行m列 memset(c,0,sizeof(c));//初始化标记 z=0;sum=1; int i,j; cout<<"Scenario #"<<b<<":"<<endl;//b第几个案列 char qq; c[1][1]=1;//访问过为做标记 1 if(bfs(1,1)==0)//有通路并遍历完 for(i=1;i<=sum;i++) { qq=a[i][0]+64;//0为字符 cout<<qq<<a[i][1];//1为数字 先输出字符再输出数字 }else cout<<"impossible";//没有结果 cout<<endl;// if(T!=0)cout<<endl;//除了最后一个案例,每个案例都要换行 案例之间要有空格 } return 0; }