1. 程式人生 > >魔板問題(搜索)

魔板問題(搜索)

pac eat 數據 string icp get virt data- 題目

問題 E: 【搜索】魔板問題

時間限制: 1 Sec 內存限制: 64 MB
提交: 23 解決: 6
[提交] [狀態] [討論版] [命題人:admin]

題目描述

據說能使持有者成為世界之主的上古神器隱藏在魔板空間,魔板由8個同樣大小的方塊組成,每個方塊顏色均不相同,按順時針方向依次寫下各方塊的顏色代號,例如序列(1,2,3,4,5,6,7,8)即代表圖所示的魔板狀態。
技術分享圖片 對於魔板可施加三種不同的操作,分別以A,B,C標識,具體操作方法如圖所示。
技術分享圖片 對於每種可能的狀態,這三種基本操作都可以使用。你要編程計算用最少的基本操作完成基本狀態到特殊狀態的轉換,輸出基本操作序列。

輸入

只有一行,包括8個整數,用空格分開(這些整數在範圍 1~8 之間),表示目標狀態。

輸出

第一行包括一個整數,表示最短操作序列的長度。

第二行在字典序中最早出現的操作序列,用字符串表示,除最後一行外,每行輸出60個字符。

樣例輸入

2 6 8 4 5 7 3 1

樣例輸出

7
BCABCCB

提示

樣例的輸入目標狀態是由BCABCCB這7步操作獲得的,如圖所示。
技術分享圖片

map記錄每個狀態以及是否出現過,bfs跑一邊即可。

#include<bits/stdc++.h>
#include<queue>
#include
<map> #include<cstring> using namespace std; const int maxn = 5e5 + 5; map<string, int>digit; map<string, string>cur; queue<string>q; string init, dis; void swap(char &x, char &y) { char t = x; x = y; y = t; } int main() { int x;
for (int k = 1; k <= 8; k++) { cin>>x; init += (char)(k + 0), dis += (char)(x + 0); } q.push(init), digit[init] = 1; while (!q.empty()) { string u = q.front(); string tmp=u; q.pop(); if (u == dis)break; swap(tmp[0], tmp[7]), swap(tmp[1], tmp[6]), swap(tmp[2], tmp[5]), swap(tmp[3], tmp[4]); if (!digit[tmp]) { q.push(tmp), cur[tmp] = cur[u] + A, digit[tmp] = 1; } tmp[0] = u[3], tmp[1] = u[0], tmp[2] = u[1], tmp[3] = u[2], tmp[7] = u[4], tmp[6] = u[7], tmp[5] = u[6], tmp[4] = u[5]; if (!digit[tmp]) { q.push(tmp), cur[tmp] = cur[u] + B, digit[tmp] = 1; } tmp[0] = u[0], tmp[7] = u[7], tmp[3] = u[3], tmp[4] = u[4], tmp[1] = u[6], tmp[2] = u[1], tmp[5] = u[2], tmp[6] = u[5]; if (!digit[tmp]) { q.push(tmp), cur[tmp] = cur[u] + C, digit[tmp] = 1; } } cout << cur[dis].length() << endl << cur[dis] << endl; return 0; }

魔板問題(搜索)