5998 Problem D【寬搜入門】魔板
阿新 • • 發佈:2018-12-04
問題 D: 【寬搜入門】魔板
時間限制: 1 Sec 記憶體限制: 128 MB
提交: 60 解決: 17
[提交][狀態][討論版][命題人:外部匯入]
題目描述
在成功地發明了魔方之後,魯比克先生髮明瞭它的二維版本,稱作魔板。這是一張有8個大小相同的格子的魔板:
1 2 3 4
8 7 6 5
我們知道魔板的每一個方格都有一種顏色。這8種顏色用前8個正整數來表示。可以用顏色的序列來表示一種魔板狀態,規定從魔板的左上角開始,沿順時針方向依次取出整數,構成一個顏色序列。對於上圖的魔板狀態,我們用序列(1,2,3,4,5,6,7,8)來表示。這是基本狀態。
這裡提供三種基本操作,分別用大寫字母“A”,“B”,“C”來表示(可以通過這些操作改變魔板的狀態):
“A”:交換上下兩行;
“B”:將最右邊的一列插入最左邊;
“C”:魔板中央四格作順時針旋轉。
下面是對基本狀態進行操作的示範:
A:
8 7 6 5
1 2 3 4
B:
4 1 2 3
5 8 7 6
C:
1 7 2 4
8 6 3 5
對於每種可能的狀態,這三種基本操作都可以使用。
你要程式設計計算用最少的基本操作完成基本狀態到目標狀態的轉換,輸出基本操作序列。
【輸入格式】
輸入有多組測試資料
只有一行,包括8個整數,用空格分開(這些整數在範圍 1——8 之間),表示目標狀態。
【輸出格式】
Line 1: 包括一個整數,表示最短操作序列的長度。
Line 2: 在字典序中最早出現的操作序列,用字串表示,除最後一行外,每行輸出60個字元。
Sample Input
2 6 8 4 5 7 3 1
Sample Output
7
BCABCCB
#include<iostream> #include<cstdio> #include<queue> #include<vector> #include<map> #include<algorithm> using namespace std; int termination; //注意要進入下一層後轉化回來也得寫 struct node { int num, step; vector<char> answer; node(int n, int s, vector<char> a) { num = n, step = s, answer = a; } }; void oper(char str[],int flag,bool operate) { if (flag == 0) { for (int i = 0; i < 4; i++) { swap(str[i], str[7 - i]); } } else if (flag == 1) { if (operate == true) { char t1 = str[3], t2 = str[4]; for (int i = 2; i >= 0; i--) { str[i + 1] = str[i]; } for (int i = 5; i < 8; i++) { str[i - 1] = str[i]; } str[0] = t1, str[7] = t2; } else { char t1 = str[0], t2 = str[7]; for (int i = 0; i < 3; i++) { str[i] = str[i + 1]; } for (int i = 7; i >= 5; i--) { str[i] = str[i - 1]; } str[3] = t1, str[4] = t2; } } else { if (operate == true) { char t = str[1]; str[1] = str[6], str[6] = str[5], str[5] = str[2], str[2] = t; } else { char t = str[1]; str[1] = str[2], str[2] = str[5], str[5] = str[6], str[6] = t; } } } queue<node> q; map<int, bool> mp; void BFS() { char temp[10]; int temp1, num = 12345678; vector<char> answer; node s(num, 0, answer); q.push(s); mp[num] = true; while (!q.empty()) { s = q.front(); q.pop(); if (s.num == termination) { cout << s.step << endl; for (int i = 0; i < s.step; i++) { cout << s.answer[i]; if (i % 60 == 0 && i) cout << endl; } return; } sprintf(temp, "%d", s.num); for (int i = 0; i < 3; i++) { oper(temp, i, true); sscanf(temp, "%d", &temp1); if (mp.count(temp1) == 0){ node r(temp1, s.step + 1, s.answer); r.answer.push_back(i + 'A'); q.push(r); mp[temp1] = true; } oper(temp, i, false); } } } int main() { int n; while (cin >> n) { termination = n; for (int i = 0; i < 7; i++) { cin >> n; termination = termination * 10 + n; } BFS(); } return 0; }