HOJ. 10239 The knight

8 篇文章 0 订阅

The knight

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.

Input

There is only one number N (1 <= N <= 15) in the input.

Output

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”.

Sample Input

5

Sample Output

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();
    }
}


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值