Java?九宮重排(滿分解法)
題目
如下圖的九宮格中,放著 1 ~ 8 的數(shù)字卡片,還有一個(gè)格子空著。與空格子相鄰的格子中的卡片可以移動(dòng)到空格中。 經(jīng)過(guò)若干次移動(dòng),可以形成圖 2 所示的局面。

我們把上圖的局面記為:12345678.
把下圖的局面記為:123.46758

顯然是按從上到下,從左到右的順序記錄數(shù)字,空格記為句點(diǎn)。
題目的任務(wù)是已知九宮的初態(tài)和終態(tài),求最少經(jīng)過(guò)多少步的移動(dòng)可以到達(dá)。如果無(wú)論多少步都無(wú)法到達(dá),則輸出 -1。
輸入描述
輸入第一行包含九宮的初態(tài),第二行包含九宮的終態(tài)。
輸出描述
輸出最少的步數(shù),如果不存在方案,則輸出 -1。
輸入
12345678.
123.46758
輸出
3
思路
求最少步數(shù),典型的廣搜
- 題目讓我們求最少步數(shù),我們可以模擬空格的移動(dòng)
- 通過(guò)字符串的下標(biāo)交換字符位置,模擬字符串的上下左右的移動(dòng),每次移動(dòng)通過(guò)set判斷該狀態(tài)是否已經(jīng)移動(dòng)過(guò),如果沒(méi)有就入隊(duì)列
- 上(-3)下(+3)左(-1)右(+1)
- 判斷每次的下標(biāo)是否合法,越界只要判斷示是否在字符串長(zhǎng)度范圍內(nèi)
關(guān)鍵代碼:
(pos%3 != index%3 && pos/3 != index/3)
因?yàn)楫?dāng)前位置和上下都只是差3,左右都只是差1
如果是左右就一定滿足,下標(biāo)/3相等
如果是上下就一定滿足,下標(biāo)%3相等

代碼
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String start = sc.next();
String end = sc.next();
// 枚舉字符串下標(biāo)的上下左右
int[] upDownLeftRight = {-3,3,-1,1};
// 去重
Set<String> set = new HashSet<>();
Queue<String> queue = new LinkedList<>();
set.add(start);
queue.offer(start);
int count = 0;
// 標(biāo)記是否已經(jīng)找到
boolean flag = false;
while (!queue.isEmpty()) {
int size = queue.size();
while (size-- != 0) {
String s = queue.peek();
// 空格位置
int index = s.indexOf(".");
for (int i = 0; i < 4; i++) {
int pos = index + upDownLeftRight[i];
// 當(dāng)新的位置不是空格的上下左右或者已經(jīng)越界
if (pos < 0 || pos > 8 || (pos%3 != index%3 && pos/3 != index/3)) {
continue;
}
char c = s.charAt(pos);
char[] ch = s.toCharArray();
ch[pos] = ch[index];
ch[index] = c;
String str = new String(ch);
if (str.equals(end)) {
flag = true;
break;
}
if (set.add(str)) {
queue.offer(str);
}
}
queue.poll();
}
count++;
if (flag) {
break;
}
}
if (flag) {
System.out.println(count);
} else {
System.out.println(-1);
}
}
}

到此這篇關(guān)于Java 九宮重排(滿分解法)的文章就介紹到這了,更多相關(guān)Java 九宮重排內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
如何使用Java統(tǒng)計(jì)gitlab代碼行數(shù)
這篇文章主要介紹了如何使用Java統(tǒng)計(jì)gitlab代碼行數(shù),實(shí)現(xiàn)方式通過(guò)git腳本將所有的項(xiàng)目拉下來(lái)并然后通過(guò)進(jìn)行代碼行數(shù)的統(tǒng)計(jì),需要的朋友可以參考下2023-10-10
零基礎(chǔ)如何系統(tǒng)的學(xué)習(xí)Java
這篇文章主要介紹了零基礎(chǔ)如何系統(tǒng)的學(xué)習(xí)Java,很多朋友糾結(jié)這個(gè)問(wèn)題,教材書(shū)不知道從何學(xué)起,今天小編給大家分享一篇教程幫助到家梳理這方面的知識(shí)2020-07-07
Java通過(guò) Socket 實(shí)現(xiàn) TCP服務(wù)端
這篇文章主要介紹了Java通過(guò) Socket 實(shí)現(xiàn) TCP服務(wù)端的相關(guān)資料,需要的朋友可以參考下2017-05-05
Spring?Boot?Admin集成與自定義監(jiān)控告警示例詳解
SpringBootAdmin是一個(gè)管理和監(jiān)控SpringBoot應(yīng)用程序的工具,可通過(guò)集成和配置實(shí)現(xiàn)應(yīng)用監(jiān)控與告警功能,本文給大家介紹Spring?Boot?Admin集成與自定義監(jiān)控告警示例詳解,感興趣的朋友跟隨小編一起看看吧2024-09-09
舉例講解Java的RTTI運(yùn)行時(shí)類型識(shí)別機(jī)制
這篇文章主要介紹了Java的RTTI運(yùn)行時(shí)類型識(shí)別機(jī)制,包括泛化的Class引用以及類型檢查instanceof等知識(shí)點(diǎn),需要的朋友可以參考下2016-05-05

