題目:
初始正方形中的帶圓圈的數字是可以移動到沿着行的其他正方形的標記。 在拼圖的每個步驟,可以移動標記的正方形中由當前佔據的整數指示的方格數。 標記可以沿着該行向左或向右移動,但可以不移動經過任一端。 例如,唯一合法的第一步是將標記向右移動三個方格,因爲沒有空間向左移動三個空格。拼圖的目標是將標記移動到行的遠端的0。
要求
如果圓圈能夠移動到最後0的位置,返回true,否則返回false。
程序要適應任何大小的方格數,並且方格里的數字是隨機的,範圍是[1,9]。
輸出圓圈走過的路徑。
主要思路:
在puzzle類中,用num表示當前格子內的值,sign標記該格子走過的方向,-1表示向左移動,1表示向右移動,0表示沒有移動過,2表示兩邊都移動過了。先將第一個值入棧,首先判斷當前下標是否是最後一個格子的下標,即是否到達0,如果當前下標是最後一個格子的下標,到達最後的0,返回stack。否則根據sign的值判斷其移動方向,如果是0,判斷其能否進行左移和右移,可以的話,進行移動且入棧,並改變sign和index的值。如果不行,當前元素出棧。
這裏我用lastIndex表示上一個入棧元素的下標。出棧之後,將index更新爲lastIndex。
如果右移過即sign == 1 那麼只需判斷能否左移,如果可以,進行左移並 sign 賦值爲2,否則,出棧,將index更新爲lastIndex。
同樣如果左移過即sign == -1 那麼只需判斷能否右移,如果可以,進行右移並 sign 賦值爲2.否則,出棧,將index更新爲lastIndex。
返回值我用的的Stack,如果棧爲空或者棧的peek()元素不是0,那麼表示沒有成功。如果peek()元素值的是0,表示成功
puzzle.java代碼
public class Puzzle {
private int num; //值
private int sign; //標記
private int index; //保存下標
public Puzzle(int num,int index){
this.num = num;
this.index = index;
sign = 0;
}
public int getIndex() {
return index;
}
public void setIndex(int index) {
this.index = index;
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
public int getSign() {
return sign;
}
public void setSign(int sign) {
this.sign = sign;
}
}
Test.java代碼
public class Test { //用棧實現puzzle
public static void main(String[] args) {
int[] arr = new int[]{4,8,5,2,3,5,1,6,4,0};
Puzzle[] puzzle = new Puzzle[arr.length];
for (int i=0;i<arr.length;i++){
puzzle[i] = new Puzzle(arr[i],i);
System.out.print(puzzle[i].getNum()+" ");
}
System.out.println();
Stack<Puzzle> stack = run(puzzle);
if(stack.isEmpty()){
System.out.println("無解");
}else{
if (stack.peek().getNum() == 0){
print(stack);
}else{
System.out.println("無解");
print(stack);
}
}
}
public static void print(Stack<Puzzle> stack){
System.out.println("走過的路徑倒序輸出爲:");
while(!stack.isEmpty()){
System.out.println(stack.peek().getNum());
stack.pop();
}
}
private static Stack<Puzzle> run(Puzzle[] puzzles) {
Stack<Puzzle> stack = new Stack();
int index=0; //index代表當前數組下標
if (puzzles[0].getNum() != 0){
stack.push(puzzles[index]);
}else{
return stack;
}
while(!stack.isEmpty()){
int num = stack.peek().getNum();
int sign = stack.peek().getSign();
int lastIndex = stack.lastElement().getIndex(); //上一個入棧元素的下標
if (sign == 0){ //沒移動過
if (puzzles.length-1 == index) {
return stack;
}else if(puzzles.length-1 - index >= num){
//右移
stack.push(puzzles[index+num]);
puzzles[index].setSign(1);
index += num;
}else if(index >= num){
//左移
stack.push(puzzles[index-num]);
puzzles[index].setSign(-1);
index -= num;
}else{
stack.pop();
index = lastIndex;
}
}else if (sign == 1){ //右邊移動過了
if (index >= num){ //可以左移
stack.push(puzzles[index-num]);
puzzles[index].setSign(2); //當前點兩邊都移動過了,置爲2;
index -= num;
}else{
stack.pop();
index = lastIndex;
}
}else if(sign == -1){ //左移過了
if (puzzles.length-1 - index >= num){ //可以右移
//右移
stack.push(puzzles[index+num]);
puzzles[index].setSign(2); //當前點兩邊都移動過了,置爲2;
index += num;
}else{
stack.pop();
index = lastIndex;
}
}else{ //都移動過了
return stack;
}
}
return stack;
}
}