62,614
社区成员
发帖
与我相关
我的任务
分享
// Find a *single* closed knight's tour
// (Sequential & iterative version, not optimised)
import java.util.*;
class Position {
static final int numRows = 3; // number of rows on board
static final int numCols = 10; // number of columns on board
static final Position end1 = new Position(1,2); // possible end positions (start is (0,0)
static final Position end2 = new Position(2,1); // other possible end position
private int row; // row number, o<=i<numRows
private int col; // column number, o<=j<numCols
Position(int row0,int col0) {
row = row0; col = col0;
}
public boolean equals(Object obj) { // compare with another position
if (obj==null) return false;
Position p = (Position) obj;
return (p.row==row && p.col==col);
}
Position[] knightMoves() { //list of knight's possible moves from here
Position[] temp = new Position[8];
int count = 0; // temp[0..count-1] holds results
int[] xStep = {2, 2, -2, -2, 1, 1, -1, -1}; // potential moves are (row+yStep[k],col+xStep[k]) for each index k
int[] yStep = {1, -1, 1, -1, 2, -2, 2, -2};
for (int k=0; k<xStep.length; k++) { // check that each potential move stays on board
int x = row+yStep[k];
int y = col+xStep[k];
if (0<=x && x<numCols && 0<=y && y<numRows) {
temp[count] = new Position(x,y); count++;
}
}
Position[] result = new Position[count];
for (int k=0; k<count; k++)
result[k] = temp[k];
return result;
}
void putPosition() { // print position
System.out.print("("+row+","+col+")");
}
}
class Path { // non-empty path of Position's
private Position start; // one end position in path (other is (0,0))
private Path next; // path following start node (may be null)
private int pathLength; // length of path
Path(Position start0, Path next0) {
start = start0; next = next0;
if (next==null)
pathLength = 1;
else
pathLength = 1 + next.pathLength;
}
boolean contains(Position p) { // does p occur in this path?
if (start.equals(p)) return true;
else if (next==null) return false;
else return next.contains(p);
}
Position[] pathMoves() { // new positions to extend path
return start.knightMoves();
}
boolean pathComplete() { // does the path cover the entire board?
int tourLength = Position.numRows*Position.numCols;
return pathLength == tourLength;
}
boolean pathClosed() { // is the path (assumed complete) closed?
return start.equals(Position.end1) || start.equals(Position.end2);
}
void putPath() { // print path
start.putPosition();
if (next!=null) {
System.out.print(":");
next.putPath();
}
}
}
class KnightsTourSingleItSeq {
private static void knightsTour() {
LinkedList<Path> workQ = new LinkedList<Path>();
workQ.add(new Path(new Position(0,0), null));
while (!workQ.isEmpty()) {
Path path = workQ.removeLast();
Position[] moves = path.pathMoves();
for (Position pos : moves) {
if (!path.contains(pos)) {
Path newPath = new Path(pos, path);
if (newPath.pathComplete()) {
if (newPath.pathClosed())
newPath.putPath();
System.out.println();
return;
}
else workQ.add(newPath);
}
}
}
}
public static void main(String[] args) {
long startTime = System.nanoTime();
knightsTour();
long endTime = System.nanoTime();
long time = (endTime-startTime)/1000000;
System.out.println("Running time = " + time);
}
}