A Knight's Journey
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 36713 | Accepted: 12469 |
Description
Background
The knight is getting bored of seeing the same black and white squares again and again and has decided to make a journey
around the world. Whenever a knight moves, it is two squares in one direction and one square perpendicular to this. The world of a knight is the chessboard he is living on. Our knight lives on a chessboard that has a smaller area than a regular 8 * 8 board, but it is still rectangular. Can you help this adventurous knight to make travel plans?
Problem
Find a path such that the knight visits every square once. The knight can start and end on any square of the board.
The knight is getting bored of seeing the same black and white squares again and again and has decided to make a journey
around the world. Whenever a knight moves, it is two squares in one direction and one square perpendicular to this. The world of a knight is the chessboard he is living on. Our knight lives on a chessboard that has a smaller area than a regular 8 * 8 board, but it is still rectangular. Can you help this adventurous knight to make travel plans?
Problem
Find a path such that the knight visits every square once. The knight can start and end on any square of the board.
Input
The input begins with a positive integer n in the first line. The following lines contain n test cases. Each test case consists of a single line with two positive integers p and q, such that 1 <= p * q <= 26. This represents a p * q chessboard, where p describes how many different square numbers 1, . . . , p exist, q describes how many different square letters exist. These are the first q letters of the Latin alphabet: A, . . .
Output
The output for every scenario begins with a line containing "Scenario #i:", where i is the number of the scenario starting at 1. Then print a single line containing the lexicographically first path that visits all squares of the chessboard with knight moves followed by an empty line. The path should be given on a single line by concatenating the names of the visited squares. Each square name consists of a capital letter followed by a number.
If no such path exist, you should output impossible on a single line.
If no such path exist, you should output impossible on a single line.
Sample Input
3 1 1 2 3 4 3
Sample Output
Scenario #1: A1 Scenario #2: impossible Scenario #3: A1B3C1A2B4C2A3B1C3A4B2C4
测试数据可见http://poj.org/showmessage?message_id=162294 好的分析路径:http://blog.csdn.net/lyy289065406/article/details/6647666 花费时间:一天,还是有参考百度,自己要增加独立思考的能力
注意国际象棋中行为数字,列为字母
//第二次做的
#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> //POJ2488 A Knight's Journey #if 1 //这个顺序也是要严格按照字典序的顺序来的,要不然得到的结果就是不对的 //重新做这道题主体代码都是对的,主要就是这个顺序没弄对,还有这个 //注意马到1的位置是(-1,-2)不是(-2,-1)这个自己是严重犯了错误
//同样输出少了个\n
#define MAXINT 30 int dir[8][2] = { { -1, -2 }, { 1, -2 }, { -2, -1 }, { 2, -1 }, { -2, 1 }, { 2, 1 }, { -1, 2 }, { 1, 2 } }; char path[MAXINT][2]; //有2个长度A1就是2个长度 int visit[MAXINT][MAXINT]; int p = 0; int q = 0; void init() { int i = 0; int j = 0; for (i = 0; i < MAXINT;i++) { for (j = 0; j < MAXINT; j++) { visit[i][j] = 0; } path[MAXINT][0] = '\0'; path[MAXINT][1] = '\0'; } return; } void printfpath() { int i = 0; for (i = 1; i <= (p*q); i++) { printf("%c%c", path[i][0], path[i][1]); } printf("\n"); return; } //x负责数字,y负责字母,第1列y char GetnameZimu(int y) { return ('A' + y - 1); } char GetnameShuzi(int x) { return ('0' + x); } //p是列,p负责数字,q是行,q负责字母 int dfs(int x, int y,int num) { int i = 0; if ((x<1)||(x>p)||(y<1)||(y>q)) return 0; if ((p*q) == num) return 1; for (i = 0; i < 8;i++) { int x1 = x + dir[i][0]; int y1 = y + dir[i][1]; if ((x1<1) || (x1>p) || (y1<1) || (y1>q)) continue; if (1 == visit[x1][y1]) continue; visit[x1][y1] = 1; path[num + 1][0] = GetnameZimu(y1); path[num + 1][1] = GetnameShuzi(x1); if (1 == dfs(x1,y1,num+1)) { return 1; } else { //回溯 visit[x1][y1] = 0; path[num + 1][0] = '\0'; path[num + 1][1] = '\0'; } } return 0; } int main() { int i = 0; int T = 0; freopen("input.txt","r",stdin); scanf("%d",&T); for (i = 0; i < T;i++) { init(); scanf("%d %d", &p, &q); //可以从任何一个位置出发,那就从第一个位置出发,这个是(1,1)开始,这个是字典序中最小的 printf("Scenario #%d:\n", i + 1); visit[1][1] = 1; path[1][0] = 'A'; path[1][1] = '1'; if (1 == dfs(1, 1,1)) { printfpath(); } else { printf("impossible\n"); } printf("\n"); } return 0; } #endif
//code pojAC
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
/*3
1 1
2 3
4 3
从题意中看4 3, 4是列,4是行
*/
/*提交记录
1:第一次提交wa, 再看了下题目加百度,发现输入p,q不是那么简单理解的,自己理解成p是列,q是行,不对的,应该是p是行,q是列
2:第二次提交提示格式错误,原来输出要隔2行,好吧。。。*/
#define MAXINT 100
typedef struct info
{
char zimu;
int index;
}infos;
int p = 0;
int q = 0;
int visitsqure = 1;
int sum = 0;
int flag = 0;
int map[MAXINT][MAXINT];
char zimu[MAXINT][MAXINT];
int visit[MAXINT][MAXINT];
infos que[MAXINT*MAXINT];
//因为输出要求按照字典序,因此这个方向也是要按照字典序的方向,先拍字母,然后排数字,这个方向已定要对
int dir[8][2] = { { -1, -2 }, {1,-2}, {-2,-1}, {2,-1}, {-2,1}, {2,1}, {-1,2}, {1,2} };
int dfs(int x, int y, int step)
{
int i = 0;
if (x <= 0 || x > p || y<0 || y>q) return 0;
visit[x][y] = 1;
que[step].zimu = zimu[x][y];
que[step].index = map[x][y];
if (1 == flag) return 1;
if (step == sum)
{
flag = 1;
return 1;
}
for (i = 0; i < 8;i++)
{
int x1 = x + dir[i][0];
int y1 = y + dir[i][1];
if (x1 <= 0 || x1 > p || y1<=0 || y1>q) continue;
if (visit[x1][y1]) continue;
visit[x1][y1] = 1;
if (1 == dfs(x1, y1, step+1))
{
return 1;
}
visit[x1][y1] = 0;
}
return 0;
}
void init()
{
int k = 0;
int j = 0;
int tmp = 1;
for (j = 1; j <= p; j++)
{
for (k = 1; k <= q; k++)
{
map[j][k] = 0;
zimu[j][k] = '\0';
visit[j][k] = 0;
}
que[tmp].zimu = '\0';
que[tmp++].index = 0;
}
visitsqure = 1;
sum = 0;
flag = 0;
return;
}
//从第一点出发
int main()
{
int T = 0;
int i = 0;
int j = 0;
int k = 0;
int zimuindex = 65; //小a 97,大A65
freopen("input.txt", "r", stdin);
scanf("%d",&T);
for (i = 0; i < T;i++)
{
scanf("%d %d", &p, &q);
init();
sum = p*q;
zimuindex = 65;
for (j = 1; j <= q;j++)
{
for (k = 1; k <= p; k++)
{
map[k][j] = k;
zimu[k][j] = zimuindex; //输入也要注意,之前自己就弄错了,输入好像还是弄错了,p是行,q是列,自己以为输入是列,行,不对,是行,列
}
zimuindex += 1;
}
//要求是按照字典序的顺序输出的
if (1 == dfs(1, 1, 1))//从1行1列经过
{
printf("Scenario #%d:\n", i + 1);
for (j = 1; j <= sum;j++)
{
printf("%c%d", que[j].zimu, que[j].index);
}
printf("\n\n");
}
else
{
printf("Scenario #%d:\n",i+1);
printf("impossible\n\n");
}
}
return 0;
}