Time Limit: 1000ms, Special Time Limit:2500ms, Memory Limit:32768KB
Total submit users: 141, Accepted users: 112
Problem 10239 : Special judge
Problem description
Even paratroopers have vacations. The flight to Sirius in the depths of “The Admiral Brisco” Leo Hao whiled away with chessboard. No, he did not like usual chess game, and in addition, he did not have likely rival. The whole day Leo amused himself with an interesting thing: he tried to travel over all cells of the chessboard with the knight so that the knight visited each cell only one time. Leo attempted one time, then second, but always something was wrong. Leo became a little angry. Then he attempted board 44 instead of 88. Again failure after failure. A little angry, with the chessboard under his arm, Leo went to look for a local programmer. They two together indeed will solve this problem.
There is only one number N (1 <= N <= 15) in the input.
If it is possible to travel with the knight over the square field N×N cells, then output should contain N^2 lines with tour over the chessboard with mentioned property, otherwise the only word “IMPOSSIBLE”.
5
aA
bC
aE
cD
eE
dC
eA
cB
aC
bA
dB
eD
cE
aD
bB
dA
eC
dE
bD
aB
cA
eB
cC
bE
dD
Problem Source
IX Open Collegiate Programming Contest 2004
回溯题,每个最多8个方向,对8个方向进行暴力DFS搜索即可
需要注意的是,可以贪心地优先选择成功可能性大的路径进行搜索。
而成功的可能性可以靠可以走的点的个数大致量化
直接上代码:
/*
* Copyright (c) 2019 Ng Kimbing, HNU, All rights reserved. May not be used, modified, or copied without permission.
* @Author: Ng Kimbing, HNU.
* @LastModified:2019-05-19 T 10:22:41.735 +08:00
*/
package ACMProblems;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import static ACMProblems.ACMIO.*; //My IO
public class LiuJuan {
static class Point {
int x;
int y;
Point(int x, int y) {
this.x = x;
this.y = y;
}
}
static class Direction {
int num;
int directionIndex;
Direction(int num, int directionIndex) {
this.num = num;
this.directionIndex = directionIndex;
}
}
private static final int MAX_N = 100;
private static boolean[][] visited = new boolean[MAX_N][MAX_N];
private static boolean found = false;
private static int n;
private static ArrayList<Point> currPath = new ArrayList<Point>();
private static int dir[][] = {{2, -1}, {1, -2}, {-1, -2}, {-2, -1}, {-2, 1}, {-1, 2}, {1, 2}, {2, 1}};
private static int countDirection(int x, int y) {
int cnt = 0;
for (int i = 0; i < 8; i++) {
int newX = x + dir[i][0];
int newY = y + dir[i][1];
if (!outOfBound(newX, newY) && !visited[newX][newY])
cnt++;
}
return cnt;
}
private static boolean outOfBound(int x, int y) {
return x < 0 || x >= n || y < 0 || y >= n;
}
private static void dfs(int x, int y, int depth) {
if (found || outOfBound(x, y) || visited[x][y])
return;
++depth;
visited[x][y] = true;
currPath.add(new Point(x, y));
//OK
if (depth == n * n) {
for (Point k : currPath)
out.println((char) (k.x + 'a') + "" + (char) (k.y + 'A'));
found = true;
return;
}
Direction[] direction = new Direction[8];
int pos = 0;
for (int i = 0; i < 8; i++) {
int newX = x + dir[i][0];
int newY = y + dir[i][1];
int cnt = countDirection(newX, newY);
if (!outOfBound(newX, newY) && !visited[newX][newY])
direction[pos++] = new Direction(cnt, i);
}
//greedy
Arrays.sort(direction, 0, pos, Comparator.comparingInt(o -> o.num));
//For all direction..
for (int i = 0; i < pos; i++)
dfs(x + dir[direction[i].directionIndex][0], y + dir[direction[i].directionIndex][1], depth);
// dfs(x + dir[direction[i].directionIndex][0], y + dir[direction[i].directionIndex][1], ++steps);
visited[x][y] = false;
currPath.remove(currPath.size() - 1);
}
public static void main(String[] args) throws Exception {
setStream(System.in);
n = nextInt();
dfs(0, 0, 0);
if (!found)
out.println("IMPOSSIBLE");
out.flush();
}
}