这道题是图论深搜的典型题。初做此题,首先觉得应当有一个邻接矩阵,于是花了很大力气将棋盘编号,最后在判断是否邻接的条件处纠结许久。
之后的搜索使用了C++的栈结构,没有使用递归(优点),但最后无论时间、代码长度、还是空间都不理想。经过学习网上大牛们的代码后,恍然
大悟,原来根本不需要构建邻接矩阵,只能说我学的太死了,完全可以使用二维数组直接模拟马的跳跃,这样判断邻接的问题就没有了。
#include <iostream> #include <stdio.h> #include <stdlib.h> #include <stack> #include <string.h> using namespace std; int main() { char board[26][26]; int num = 0; scanf("%d",&num); for(int i = 1;i <= num;i++) { int xMax,yMax; scanf("%d %d",&xMax,&yMax); //printf("%d %d",xMax,yMax); memset(board,0,sizeof(board)); int boardSize = xMax * yMax; for(int j = 0;j < boardSize;j++) { if((j + xMax + 2) < boardSize && ((j % xMax + 2) < xMax)) board[j][(j + xMax + 2)] = 1; if((j + xMax - 2) < boardSize && (j + xMax - 2) >= 0 && (j % xMax - 2) >= 0) board[j][(j + xMax - 2)] = 1; if((j - xMax + 2) < boardSize && (j - xMax + 2) >= 0 && (j % xMax + 2) < xMax) board[j][(j - xMax + 2)] = 1; if((j - xMax - 2) >= 0 && (j % xMax - 2) >= 0) board[j][(j - xMax - 2)] = 1; if((j + 2 * xMax + 1) < boardSize && (j % xMax + 1) < xMax) board[j][(j + 2 * xMax + 1)] = 1; if((j + 2 * xMax - 1) < boardSize && (j + 2 * xMax - 1) >= 0 && (j % xMax - 1) >= 0) board[j][(j + 2 * xMax - 1)] = 1; if((j - 2 * xMax + 1) < boardSize && (j - 2 * xMax + 1) >= 0 && (j % xMax + 1) < xMax) board[j][(j - 2 * xMax + 1)] = 1; if((j - 2 * xMax - 1) >= 0 && (j % xMax - 1) >= 0) board[j][(j - 2 * xMax - 1)] = 1; } char visited[26]; memset(visited,0,sizeof(visited)); bool flag = false; for(int k = 0;k < boardSize;k++) { memset(visited,0,sizeof(visited)); stack<int> s; s.push(k); visited[k] = 1; int startFrom = 0; int record[26]; memset(record,0,sizeof(record)); int recordNum = 1; flag = false; if(boardSize == 1) { flag = true; printf("Scenario #%d:\nA1\n\n",i); break; } while(!s.empty()) { int current = s.top(); int j; for(j = startFrom;j < boardSize;j++) { if((board[current][j] == 1) && visited[j] == 0) { s.push(j); visited[j] = 1; startFrom = 0; record[recordNum] = j; recordNum++; if(recordNum == boardSize) flag = true; break; } } if(flag) break; if(j == boardSize) { startFrom = s.top() + 1; visited[startFrom - 1] = 0; s.pop(); recordNum--; } } if(flag) { printf("Scenario #%d:\n",i); for(int j = 0;j < recordNum;j++) printf("%c%d",record[j] / xMax + 'A',record[j] % xMax + 1); printf("\n\n"); break; } } if(!flag) printf("Scenario #%d:\nimpossible\n\n",i); } return 0; }
#include <iostream> using namespace std; int step[8][2]={{-2,-1},{-2,1},{-1,-2},{-1,2},{1,-2},{1,2},{2,-1},{2,1}}; int main() { int a,b,ch[26][26],ss[26*26][3],s,p,x,y,j,xx,yy,ci=0; cin>>a; while(cin>>b>>a) { memset(ch,0,sizeof(ch)); p=a*b-1; s=0; ch[0][0]=1;//visit x=0; y=0; j=0; while(s>=0) { if (j<8) for (;j<8;j++) { xx=x+step[j][0]; yy=y+step[j][1]; if (ch[xx][yy]==0 && xx>=0 && xx<a && yy>=0 && yy<b) { ss[s][0]=x+65; x=xx; ss[s][1]=y+1; y=yy; ss[s][2]=j; s++; ch[xx][yy]=1; j=0; break; } } if (s==p) break; if (j==8) { s--; if (s>=0) { ch[x][y]=0; x=ss[s][0]-65; y=ss[s][1]-1; j=ss[s][2]+1; } } } ++ci; printf("Scenario #%d:\n",ci); if (s==p) { for (p=0;p<s;p++) cout<<char(ss[p][0])<<ss[p][1]; x+=65; cout<<char(x)<<y+1; } else cout<<"impossible"; cout<<endl<<endl; } return 0; }