- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在研究骑士之旅问题。在我的程序中,用户可以选择等于 3 或更大的数字 n。该数字将确定二维数组中 n*n 的表大小。然后,只要起点大于或等于0,小骑士就会根据用户给出的起点开始旅行。
当骑士走到死胡同时(截至输出中可视化表中的第 12 回合),我的问题就出现了。我想以某种方式跟踪它的运动,这样我就可以堵住死胡同,后退一步并从那里尝试。我发现我可能需要一个三维数组,以便我可以保存每个方 block 中的所有转弯数字。但话又说回来,我需要一个不是静态的 ArrayList。任何建议将不胜感激。这是我的代码:
package knightsTour;
import java.util.Scanner;
import java.util.ArrayList;
public class KnightsTour
{
private static int turns = 0;
private static ArrayList<String> moves = new ArrayList<String>();
private static int squares;
private static int table[][];
private static boolean takeTour(int x, int y) {
// Checks if all squares is used. If true, algorithm will stop
if (checkIfFinished())
return true;
table[x][y] = ++turns;
// 2 Left, 1 Down
if (x > 1 && y < squares -1 && table[x-2][y+1] == 0)
{
moves.add("X: " + x + ", Y: " + y + ". Moving 2 Left, 1 Down. Turn: " + turns);
if (takeTour(x-2, y+1))
{
return true;
}
else
{
return false;
}
}
// 2 Left, 1 Up
if (x > 1 && y > 0 && table[x-2][y-1] == 0)
{
moves.add("X: " + x + ", Y: " + y + ". Moving 2 Left, 1 Up. Turn: " + turns);
if (takeTour(x-2, y-1))
{
return true;
}
else
{
return false;
}
}
// 2 Up, 1 Left
if (y > 1 && x > 0 && table[x-1][y-2] == 0)
{
moves.add("X: " + x + ", Y: " + y + ". Moving 2 Up, 1 Left. Turn: " + turns);
if (takeTour(x-1, y-2))
{
return true;
}
else
{
return false;
}
}
// 2 Up, 1 Right
if (y > 1 && x < squares -1 && table[x+1][y-2] == 0)
{
moves.add("X: " + x + ", Y: " + y + ". Moving 2 Up, 1 Right. Turn: " + turns);
if (takeTour(x+1, y-2))
{
return true;
}
else
{
return false;
}
}
// 2 Right, 1 Up
if (x < squares -2 && y > 0 && table[x+2][y-1] == 0)
{
moves.add("X: " + x + ", Y: " + y + ". Moving 2 Right, 1 Up. Turn: " + turns);
if (takeTour(x+2, y-1))
{
return true;
}
else
{
return false;
}
}
// 2 Right, 1 Down
if (x < squares -2 && y < squares -1 && table[x+2][y+1] == 0)
{
moves.add("X: " + x + ", Y: " + y + ". Moving 2 Right, 1 Down. Turn: " + turns);
if (takeTour(x+2, y+1))
{
return true;
}
else
{
return false;
}
}
// 2 Down, 1 Right
if (y < squares -2 && x < squares-1 && table[x+1][y+2] == 0)
{
moves.add("X: " + x + ", Y: " + y + ". Moving 2 Down, 1 Right. Turn: " + turns);
if (takeTour(x+1, y+2))
{
return true;
}
else
{
return false;
}
}
// 2 Down, 1 Left
if (y < squares -2 && x > 0 && table[x-1][y+2] == 0)
{
moves.add("X: " + x + ", Y: " + y + ". Moving 2 Down, 1 Left. Turn: " + turns);
if (takeTour(x-1, y+2))
{
return true;
}
else
{
return false;
}
}
/*
I need some code here before it gives up searching
*/
// If we'd tried every single paths
// and we still end up here, there's no solution
return false;
}
// Checks if all squares is used
private static boolean checkIfFinished()
{
for (int i = 0; i < squares; i++)
{
for (int j = 0; j < squares; j++)
{
if (table[i][j] == 0)
return false;
}
}
return true;
}
// Made this to save code from 3 duplicates
private static void invalidNumber()
{
System.out.println("Invalid number! Killing proccess");
System.exit(0);
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.print("Number of squares: ");
squares = Integer.parseInt(sc.nextLine());
if (squares < 3 )
invalidNumber();
System.out.println("Note: Start values is from 0 -> n-1"
+ "\n0,0 is at top left side");
System.out.print("X start value: ");
int x = Integer.parseInt(sc.nextLine());
if (x < 0 || x > squares -1)
invalidNumber();
System.out.print("Y start value: ");
int y = Integer.parseInt(sc.nextLine());
if (y < 0 || y > squares -1)
invalidNumber();
sc.close();
table = new int[squares][squares];
boolean tourComplete = takeTour(x, y);
for (String s : moves)
{
System.out.println(s);
}
if (!tourComplete)
System.out.println("Did not find any way to complete Knights Tour!");
// Print the table with the move-numbers
for (int i = 0; i < squares; i++)
{
for (int j = 0; j < squares; j++)
{
System.out.printf("%4d", table[j][i]);
}
System.out.println();
}
}
}
我的 4*4 表格输出如下所示:
Number of squares: 4
Note: Start values is from 0 -> n-1
0,0 is at top left side
X start value: 0
Y start value: 0
X: 0, Y: 0. Moving 2 Right, 1 Down. Turn: 1
X: 2, Y: 1. Moving 2 Left, 1 Down. Turn: 2
X: 0, Y: 2. Moving 2 Up, 1 Right. Turn: 3
X: 1, Y: 0. Moving 2 Right, 1 Down. Turn: 4
X: 3, Y: 1. Moving 2 Left, 1 Down. Turn: 5
X: 1, Y: 2. Moving 2 Up, 1 Right. Turn: 6
X: 2, Y: 0. Moving 2 Left, 1 Down. Turn: 7
X: 0, Y: 1. Moving 2 Right, 1 Down. Turn: 8
X: 2, Y: 2. Moving 2 Left, 1 Down. Turn: 9
X: 0, Y: 3. Moving 2 Up, 1 Right. Turn: 10
X: 1, Y: 1. Moving 2 Right, 1 Up. Turn: 11
Did not find any way to complete Knights Tour!
1 4 7 12
8 11 2 5
3 6 9 0
10 0 0 0
最佳答案
当在 BackTracking 上尝试不同的可能性时,您需要在每个递归步骤中检查所有可能性。在您一步提供的代码中,您仅尝试一种可能性,然后返回。这样做您无法探索所有可能性。
我的建议是更改函数参数以接受当前位置 (x,y) 和先前访问过的位置的 boolean 数组。如果你需要构建最终有效解决方案的路径,我还建议添加步数(你已经完成的步数)和一个 int 数组来存储哪一步访问了哪个位置。
接下来我提供一个不是最有效的解决方案。事实上,您可以尝试修剪回溯的可能性,以避免递归爆炸(CPU 效率),并且可以尝试避免某些矩阵副本(内存效率)。
package knightsTour;
import java.util.Scanner;
public class KnightsTour {
private static final int[] MOVE_X = new int[] { -2, -2, -1, -1, +1, +1, +2, +2 };
private static final int[] MOVE_Y = new int[] { +1, -1, +2, -2, +2, -2, +1, -1 };
private final int SQUARES;
private final int INIT_X;
private final int INIT_Y;
private int[][] path;
public KnightsTour(int squares, int x, int y) {
this.SQUARES = squares;
this.INIT_X = x;
this.INIT_Y = y;
}
public int[][] getPath() {
return this.path;
}
public boolean takeTour() {
boolean[][] visited = new boolean[this.SQUARES][this.SQUARES];
for (int i = 0; i < this.SQUARES; ++i) {
for (int j = 0; j < this.SQUARES; ++j) {
visited[i][j] = false;
}
}
visited[this.INIT_X][this.INIT_Y] = true;
this.path = new int[this.SQUARES][this.SQUARES];
return takeTourBT(this.INIT_X, this.INIT_Y, 0, visited, this.path);
}
private boolean takeTourBT(int posX, int posY, int step, boolean[][] visited, int[][] path) {
debug(step, visited);
if (checkIfFinished(visited)) {
return true;
}
// Increase the step count
++step;
// Try recursively (cut when a branch success)
boolean success = false;
for (int i = 0; i < MOVE_X.length && !success; ++i) {
int nextX = posX + MOVE_X[i];
int nextY = posY + MOVE_Y[i];
if (nextX >= 0 && nextX < this.SQUARES && nextY >= 0 && nextY < this.SQUARES && !visited[nextX][nextY]) {
// Next position is valid and has not been visited
// Mark position
visited[nextX][nextY] = true;
// Call
boolean branchSuccess = takeTourBT(nextX, nextY, step, visited, path);
if (branchSuccess) {
// We are comming back from the good solution, mark the path
path[nextX][nextY] = step;
}
success = success | branchSuccess;
// Unmark the position for next try
visited[nextX][nextY] = false;
}
}
return success;
}
// Adds some verbose for debugging
private void debug(int step, boolean[][] visited) {
System.out.println("*********************** STEP " + String.valueOf(step) + " ***********************");
for (int i = 0; i < this.SQUARES; ++i) {
for (int j = 0; j < this.SQUARES; ++j) {
if (visited[i][j]) {
System.out.print("X ");
} else {
System.out.print(". ");
}
}
System.out.println("");
}
System.out.println("*******************************************************");
}
// Checks if all squares is used
private boolean checkIfFinished(boolean[][] visited) {
for (int i = 0; i < this.SQUARES; ++i) {
for (int j = 0; j < this.SQUARES; ++j) {
if (!visited[i][j]) {
return false;
}
}
}
return true;
}
public static void main(String[] args) {
// Process arguments
int squares = 0;
int x = 0;
int y = 0;
try (Scanner sc = new Scanner(System.in)) {
System.out.print("Number of squares: ");
squares = Integer.parseInt(sc.nextLine());
if (squares < 3) {
throw new Exception("[ERROR] Invalid number of squares");
}
System.out.println("Note: Start values is from 0 -> n-1" + "\n0,0 is at top left side");
System.out.print("X start value: ");
x = Integer.parseInt(sc.nextLine());
if (x < 0 || x > squares - 1) {
throw new Exception("[ERROR] Invalid start x position");
}
System.out.print("Y start value: ");
y = Integer.parseInt(sc.nextLine());
if (y < 0 || y > squares - 1) {
throw new Exception("[ERROR] Invalid start y position");
}
} catch (Exception e) {
// Error occurred, exit
System.err.println("Killing process");
System.exit(1);
}
// Initialize the KnightsTour
KnightsTour kt = new KnightsTour(squares, x, y);
// Make the tour
boolean success = kt.takeTour();
// Post process
if (success) {
System.out.println("The tour was sucessfull!");
} else {
System.out.println("Did not find any way to complete Knights Tour!");
}
int[][] path = kt.getPath();
for (int i = 0; i < path.length; ++i) {
for (int j = 0; j < path[i].length; ++j) {
String stepSTR = (path[i][j] < 10) ? "0" + String.valueOf(path[i][j]) : String.valueOf(path[i][j]);
System.out.print(stepSTR + " ");
}
System.out.println("");
}
}
}
尝试使用大小为 5 和起始位置 (0,0) 的代码。
请注意:
关于java 递归 - 需要帮助解决回溯骑士之旅,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42723630/
我正在编写一个具有以下签名的 Java 方法。 void Logger(Method method, Object[] args); 如果一个方法(例如 ABC() )调用此方法 Logger,它应该
我是 Java 新手。 我的问题是我的 Java 程序找不到我试图用作的图像文件一个 JButton。 (目前这段代码什么也没做,因为我只是得到了想要的外观第一的)。这是我的主课 代码: packag
好的,今天我在接受采访,我已经编写 Java 代码多年了。采访中说“Java 垃圾收集是一个棘手的问题,我有几个 friend 一直在努力弄清楚。你在这方面做得怎么样?”。她是想骗我吗?还是我的一生都
我的 friend 给了我一个谜语让我解开。它是这样的: There are 100 people. Each one of them, in his turn, does the following
如果我将使用 Java 5 代码的应用程序编译成字节码,生成的 .class 文件是否能够在 Java 1.4 下运行? 如果后者可以工作并且我正在尝试在我的 Java 1.4 应用程序中使用 Jav
有关于why Java doesn't support unsigned types的问题以及一些关于处理无符号类型的问题。我做了一些搜索,似乎 Scala 也不支持无符号数据类型。限制是Java和S
我只是想知道在一个 java 版本中生成的字节码是否可以在其他 java 版本上运行 最佳答案 通常,字节码无需修改即可在 较新 版本的 Java 上运行。它不会在旧版本上运行,除非您使用特殊参数 (
我有一个关于在命令提示符下执行 java 程序的基本问题。 在某些机器上我们需要指定 -cp 。 (类路径)同时执行java程序 (test为java文件名与.class文件存在于同一目录下) jav
我已经阅读 StackOverflow 有一段时间了,现在我才鼓起勇气提出问题。我今年 20 岁,目前在我的家乡(罗马尼亚克卢日-纳波卡)就读 IT 大学。足以介绍:D。 基本上,我有一家提供簿记应用
我有 public JSONObject parseXML(String xml) { JSONObject jsonObject = XML.toJSONObject(xml); r
我已经在 Java 中实现了带有动态类型的简单解释语言。不幸的是我遇到了以下问题。测试时如下代码: def main() { def ks = Map[[1, 2]].keySet()
一直提示输入 1 到 10 的数字 - 结果应将 st、rd、th 和 nd 添加到数字中。编写一个程序,提示用户输入 1 到 10 之间的任意整数,然后以序数形式显示该整数并附加后缀。 public
我有这个 DownloadFile.java 并按预期下载该文件: import java.io.*; import java.net.URL; public class DownloadFile {
我想在 GUI 上添加延迟。我放置了 2 个 for 循环,然后重新绘制了一个标签,但这 2 个 for 循环一个接一个地执行,并且标签被重新绘制到最后一个。 我能做什么? for(int i=0;
我正在对对象 Student 的列表项进行一些测试,但是我更喜欢在 java 类对象中创建硬编码列表,然后从那里提取数据,而不是连接到数据库并在结果集中选择记录。然而,自从我这样做以来已经很长时间了,
我知道对象创建分为三个部分: 声明 实例化 初始化 classA{} classB extends classA{} classA obj = new classB(1,1); 实例化 它必须使用
我有兴趣使用 GPRS 构建车辆跟踪系统。但是,我有一些问题要问以前做过此操作的人: GPRS 是最好的技术吗?人们意识到任何问题吗? 我计划使用 Java/Java EE - 有更好的技术吗? 如果
我可以通过递归方法反转数组,例如:数组={1,2,3,4,5} 数组结果={5,4,3,2,1}但我的结果是相同的数组,我不知道为什么,请帮助我。 public class Recursion { p
有这样的标准方式吗? 包括 Java源代码-测试代码- Ant 或 Maven联合单元持续集成(可能是巡航控制)ClearCase 版本控制工具部署到应用服务器 最后我希望有一个自动构建和集成环境。
我什至不知道这是否可能,我非常怀疑它是否可能,但如果可以,您能告诉我怎么做吗?我只是想知道如何从打印机打印一些文本。 有什么想法吗? 最佳答案 这里有更简单的事情。 import javax.swin
我是一名优秀的程序员,十分优秀!