UVa1063/LA3807 The Rotation Game

UVa1063/LA3807 The Rotation Game

  • 題目鏈接
  • 題意
    • 輸入格式
    • 輸出格式
  • 分析
  • AC 代碼
    • IDA*
    • 分3次BFS

題目鏈接

??本題是2004年icpc亞洲區域賽上海賽區的H題

題意

??如下圖所示形狀的棋盤上分別有8個1、2、3,要往A~H方向旋轉棋盤,使中間8個方格數字相同。圖(a)進行A操作后變為圖(b),再進行C操作后變為圖(c),這正是一個目標狀態(因為中間8個方格數字相同)。要求旋轉次數最少。如果有多解,操作序列的字典序應盡量小。
The Rotation Game

輸入格式

??輸入包括不超過 30 組測試數據。每個測試數據只包括一行,包含 24 個整數,每相鄰兩個整數之間用 1 個空格隔開,表示這個 “#” 形棋盤的初始狀態。(這些整數的排列順序是從上至下,同一行的從左至右。)每兩組測試數據之間沒有換行符。輸入文件以一行 0 結束。

輸出格式

??對于每組測試數據,輸出兩行。第一行用字符 A~H 輸出操作的方法,每兩個操作字符之間沒有空格分開,如果不需要任何步數,輸出 No moves needed。第二行輸出最終狀態中最中間的 8 個格子里的數字。如果有多組解,輸出操作次數最少的一組解;如果仍有多組解,輸出字典序最小的一組。任意相鄰兩組測試數據的輸出之間不需輸出換行符。

分析

??《算法競賽入門經典》題解:

??本題是一個典型的狀態空間搜索問題,可惜如果直接套用八數碼問題的框架會超時。為什么?學完第10章的組合計數部分后會知道:8個1、8個2、8個3的全排列個數為24!/(8!*8!*8!)=9465511770。換句話說,最壞情況下最多要處理這么多結點!

??解決方法很巧妙:本題要求的是中間8個數字相同,即8個1或者8個2或者8個3。因此可以分3次求解。當目標是“中間8個數字都是1”時,2和3就沒有區別了(都是“非1”),因此狀態總數變成了8個1,16個“非1”的全排列個數,24!/(8!*16!)=735471,在可以接受的范圍內了。

??非常好的狀態空間分析思路,按這個思路寫BFS,雖然較慢但能通過。用迭代加深搜索IDDFS會快一些,最優的方法還是IDA*,其啟發式函數可以這樣定:當前操作完成后,統計中間8個數字1、2、3數量的最大值x,則至少還需要8-x步操作。IDA*做法其實不需要進行狀態空間分析,也就不用分中間8個數字都是1或者2或者3三類情況了。

AC 代碼

IDA*

#include <iostream>
using namespace std;#define M 16
const int m = 8, n = 24, c[] = {6, 7, 8, 11, 12, 15, 16, 17}, f[] = {5, 4, 7, 6, 1, 0, 3, 2},idx[][7] = {{0, 2, 6, 11, 15, 20, 22}, {1, 3, 8, 12, 17, 21, 23},{10, 9, 8, 7, 6, 5, 4}, {19, 18, 17, 16, 15, 14, 13},{23, 21, 17, 12, 8, 3, 1}, {22, 20, 15, 11, 6, 2, 0},{13, 14, 15, 16, 17, 18, 19}, {4, 5, 6, 7, 8, 9, 10}};
int v[n]; char a[M+1];int h() {int cnt[] = {0, 0, 0, 0}, mx = 0;for (int j=0; j<m; ++j) mx = max(mx, ++cnt[v[c[j]]]);return m - mx;
}bool IDAStar(int s, int d) {if (s == d) {for (int i=1; i<m; ++i) if (v[c[i]] != v[c[i-1]]) return false;return true;} else for (int i=0; i<m; ++i) if (s == 0 || f[i] != a[s-1]-'A') {int x = v[idx[i][0]];for (int j=1, k=m-1; j<k; ++j) v[idx[i][j-1]] = v[idx[i][j]];v[idx[i][m-2]] = x; a[s] = 'A'+i;if (s+h() < d && IDAStar(s+1, d)) return true;x = v[idx[i][m-2]];for (int j=m-2; j>0; --j) v[idx[i][j]] = v[idx[i][j-1]];v[idx[i][0]] = x;}return false;
}void solve() {for (int i=1; i<n; ++i) cin >> v[i];for (int d=0; d<M; a[++d] = 0) if (IDAStar(0, d)) {cout << (d == 0 ? "No moves needed" : a) << endl << v[c[0]] << endl;break;}
}int main() {while (cin >> v[0] && v[0]) solve();return 0;
}

分3次BFS

#include <iostream>
#include <cstring>
using namespace std;#define M 735471 // C(24,8)
const int m = 8, n = 24, c[] = {6, 7, 8, 11, 12, 15, 16, 17}, f[] = {5, 4, 7, 6, 1, 0, 3, 2},idx[][7] = {{0, 2, 6, 11, 15, 20, 22}, {1, 3, 8, 12, 17, 21, 23},{10, 9, 8, 7, 6, 5, 4}, {19, 18, 17, 16, 15, 14, 13},{23, 21, 17, 12, 8, 3, 1}, {22, 20, 15, 11, 6, 2, 0},{13, 14, 15, 16, 17, 18, 19}, {4, 5, 6, 7, 8, 9, 10}};
int s[M], q[M], p[M], a[M], v[n], g[n], t, b, cc, d; char ans[50], ss[50];bool term() {for (int i=1; i<m; ++i) if (v[c[i]] != v[c[i-1]]) return false;return true;
}bool term2() {for (int i=0; i<m; ++i) if (g[c[i]] != b) return false;return true;
}void insert() {int x = 0;for (int i=0; i<n; ++i) x = x<<1 | (g[i] == b ? 1 : 0);int k = x % M;while (s[k]) {if (s[k] == x) return;k = (k+1) % M;}s[k] = x; q[t++] = k;
}void decode(int x) {for (int i=n-1; i>=0; --i) g[i] = x&1 ? b : 0, x >>= 1;
}void get_path(int f, char c, int d) {if (f) get_path(p[f], char('A'+ a[f]), d-1);ss[d] = c;
}void bfs() {memset(s, t = 0, sizeof(s)); memset(ss, 0, sizeof(ss)); memcpy(g, v, sizeof(v)); ss[0] = 'X'; a[0] = -1; insert();for (int h=0, c=t, dd=1; h<c; ++h) {int k = q[h]; decode(s[k]);for (int i=0; i<m; ++i) if (f[i] != a[h]) {int x = g[idx[i][0]];for (int j=1, k=m-1; j<k; ++j) g[idx[i][j-1]] = g[idx[i][j]];g[idx[i][m-2]] = x;if (term2()) {get_path(h, char('A'+i), dd - 1);if (dd < d || strcmp(ss, ans) < 0) memcpy(ans, ss, sizeof(ss)), cc = b, d = dd;return;}p[t] = h; a[t] = i; insert();x = g[idx[i][m-2]];for (int j=m-2; j>0; --j) g[idx[i][j]] = g[idx[i][j-1]];g[idx[i][0]] = x;}if (h+1 == c) {c = t;if (++dd > d) return;}}
}void solve() {for (int i=1; i<n; ++i) cin >> v[i];if (term()) {cout << "No moves needed" << endl << v[c[0]] << endl;return;}for (b=1, cc=0, d=50; b<4; ++b) bfs();cout << ans << endl << cc << endl;
}int main() {while (cin >> v[0] && v[0]) solve();return 0;
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/96391.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/96391.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/96391.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

用pywin32連接autocad 寫一個利用遺傳算法從選擇的閉合圖形內進行最優利用率的排版 ai草稿

好的&#xff0c;我們來深入細說遺傳算法&#xff08;Genetic Algorithm, GA&#xff09;在鈑金自動排版中的應用。遺傳算法 (GA) 在鈑金排版中的詳細解析遺傳算法是一種受達爾文生物進化論啟發的元啟發式優化算法。它不追求一次性找到數學上的絕對最優解&#xff0c;而是通過模…

Go語言io.Copy深度解析:高效數據復制的終極指南

在日常開發中&#xff0c;我們經常需要在不同的數據源之間復制數據。無論是文件操作、網絡傳輸還是進程通信&#xff0c;數據復制都是不可或缺的基礎操作。Go語言的標準庫提供了一個強大而高效的工具來簡化這一過程&#xff1a;io.Copy。 什么是io.Copy&#xff1f; io.Copy是G…

【Vue3】07-利用setup編寫vue(2)-setup的語法糖

其它篇章&#xff1a; 1.【Vue3】01-創建Vue3工程 2.【Vue3】02-Vue3工程目錄分析 3.【Vue3】03-編寫app組件——src 4.【Vue3】04-編寫vue實現一個簡單效果 5.【Vue3】05-Options API和Composition API的區別 6.【Vue3】06-利用setup編寫vue&#xff08;1&#xff09; 7.【Vue…

Firefox自定義備忘

1.設置firefox右鍵點擊標簽直接關閉&#xff0c;由于目前沒有插件能實現這個功能&#xff0c;只能手動設置了&#xff08;目前已知支持142和之前的版本&#xff09; firefox117右鍵關閉macWin 117版本應該可以了&#xff0c;大家可試下&#xff0c;配置方法參考之前的帖子&…

跨屏互聯KuapingCMS建站系統發布更新 增加數據看板

跨屏互聯KuapingCMS建站系統發布更新&#xff0c;增加了文章統計、產品統計、軟文統計、流量統計、pv統計、ip統計、os訪問者設備統計等等&#xff0c;整個體驗會更好&#xff0c;數據顯示更加直觀&#xff0c;可以清晰看到最近的網站數據&#xff0c;特別是對于老板&#xff0…

WebSocket連接狀態監控與自動重連實現

WebSocket連接狀態監控與自動重連實現 下面我將實現一個具有連接狀態監控和自動重連功能的WebSocket聊天室界面。 設計思路 創建直觀的連接狀態指示器實現自動重連機制&#xff0c;包括&#xff1a; 指數退避策略&#xff08;重連間隔逐漸增加&#xff09;最大重連次數限制手動…

【Vue2手錄05】響應式原理與雙向綁定 v-model

一、Vue2響應式原理&#xff08;底層基礎&#xff09; Vue2的“響應式”核心是數據變化自動觸發視圖更新&#xff0c;其實現依賴Object.defineProperty API&#xff0c;但受JavaScript語言機制限制&#xff0c;存在“數組/對象修改盲區”&#xff0c;這是理解后續內容的關鍵。 …

探索大語言模型(LLM):Ollama快速安裝部署及使用(含Linux環境下離線安裝)

前言 Ollama 是一個開源的本地化大模型運行平臺&#xff0c;支持用戶直接在個人計算機上部署、管理和交互大型語言模型&#xff08;LLMs&#xff09;&#xff0c;無需依賴云端服務。而且其混合推理的特性也使得CPU和GPU的算力能夠充分被使用&#xff0c;能夠在同等配置下跑更大…

滲透測試信息收集詳解

我們來詳細解析一下滲透測試中信息收集&#xff08;Information Gathering&#xff09;的完整內容、步驟及工具方法。信息收集是整個滲透測試的基石&#xff0c;其深度和廣度直接決定了后續測試的成功率&#xff0c;因此有“滲透測試成功與否&#xff0c;90%取決于信息收集”的…

Kafka面試精講 Day 16:生產者性能優化策略

【Kafka面試精講 Day 16】生產者性能優化策略 在“Kafka面試精講”系列的第16天&#xff0c;我們將聚焦于生產者性能優化策略。這是Kafka中極為關鍵的技術點&#xff0c;也是大廠面試中的高頻考點——尤其是在涉及高并發數據寫入、日志采集、實時數倉等場景時&#xff0c;面試…

深入解析AI溫度參數:控制文本生成的隨機性與創造性

引言 在人工智能飛速發展的今天&#xff0c;文本生成模型如GPT系列已經成為內容創作、代碼編寫、對話系統等領域的核心工具。然而&#xff0c;許多用戶在使用這些模型時&#xff0c;可能會發現輸出結果有時過于保守和重復&#xff0c;有時又過于天馬行空而缺乏連貫性。這背后其…

20250912在榮品RD-RK3588-MID開發板的Android13系統下在接電腦的時候禁止充電

20250912在榮品RD-RK3588-MID開發板的Android13系統下在接電腦的時候禁止充電 2025/9/12 10:21緣起&#xff1a;某人的電腦接榮品RD-RK3588-MID開發板的時候做APK開發板的時候&#xff0c;通過Android Studio連接榮品RD-RK3588-MID開發板。 經常斷聯/時斷時續。投訴了/抱怨了好…

Unity Addressable System 本地服務器功能驗證

1.從Package Manger里安裝Addressable 注意這里有Addressables和Addressables兩個包&#xff0c;前者是核心框架&#xff0c;處理跨平臺通用邏輯&#xff0c;比如用 地址&#xff08;Address&#xff09;來異步加載、卸載資源&#xff1b;自動做引用計數&#xff0c;避免資源泄…

碎片化采購是座金礦:數字化正重構電子元器件分銷的價值鏈

在電子元器件的分銷江湖里&#xff0c;長期存在著一條隱秘的“鄙視鏈”&#xff1a;訂單金額大、需求穩定的頭部客戶是眾星捧月的“香餑餑”&#xff0c;而需求碎片化、品類繁多的小微企業長尾訂單&#xff0c;則常被視作食之無味、棄之可惜的“雞肋”。行業固有認知告訴我們&a…

Typescript - 通俗易懂的 interface 接口,創建接口 / 基礎使用 / 可選屬性 / 只讀屬性 / 任意屬性(詳細教程)

前言 在面向對象語言中&#xff0c;接口是一個很重要的概念&#xff0c;它是對行為的抽象&#xff0c;而具體如何行動需要由類去實現。 TypeScript 中的接口是一個非常靈活的概念&#xff0c;除了可用于 對類的一部分行為進行抽象 以外&#xff0c;也常用于對「對象的形狀&…

【硬件-筆試面試題-92】硬件/電子工程師,筆試面試題(知識點:米勒效應,米勒平臺)

題目匯總版--鏈接&#xff1a; 【硬件-筆試面試題】硬件/電子工程師&#xff0c;筆試面試題匯總版&#xff0c;持續更新學習&#xff0c;加油&#xff01;&#xff01;&#xff01;-CSDN博客 【硬件-筆試面試題-92】硬件/電子工程師&#xff0c;筆試面試題&#xff08;知識點…

C語言深度入門系列:第十一篇 - 動態內存管理與數據結構:程序世界的高效算法大師

C語言深度入門系列&#xff1a;第十一篇 - 動態內存管理與數據結構&#xff1a;程序世界的高效算法大師 本章目標 本章將深入探討C語言中的動態內存管理和經典數據結構實現&#xff0c;這是從基礎編程邁向算法工程師的關鍵一步。您將掌握內存的精確控制、理解各種數據結構的本質…

Go 語言開發環境安裝與 GOPROXY 鏡像配置(含依賴管理與版本切換技巧)

在國內搭建 Go 開發環境的最大障礙不是“怎么裝”&#xff0c;而是“下不動”。本文是我在多臺 Windows / macOS / Linux 機器上踩坑后的整合筆記&#xff1a;用最穩妥的安裝方式 合理的鏡像配置 一套通吃的依賴/版本管理流程&#xff0c;把速度、穩定性和可維護性一次性解決…

崔傳波教授:以科技與人文之光,點亮近視患者的清晰視界?

崔傳波教授&#xff1a;以科技與人文之光&#xff0c;點亮近視患者的清晰視界?在臨沂新益民眼科醫院&#xff0c;有這樣一位眼科醫師——他不僅是近視矯正領域的專家&#xff0c;更是“金視青春之光手術”的研發倡導者。?崔傳波教授?以其深厚的學術功底、創新的技術理念和以…

如何寫過濾條件wrapper的使用

模糊查詢 &#xff1a;功能是&#xff1a;查詢 WORK_NUM 字段包含 ${workOrder.workNum} 的記錄。<if test"workOrder.workNum ! null and workOrder.workNum ! ">and b.WORK_NUM like CONCAT(%,CONCAT(#{workOrder.workNum},%)) </if>一、比較條件方法示…