Acwing 181 迴轉遊戲 (IDA*)
阿新 • • 發佈:2020-07-26
題面
如下圖所示,有一個“#”形的棋盤,上面有1,2,3三種數字各8個。
給定8種操作,分別為圖中的A~H。
這些操作會按照圖中字母和箭頭所指明的方向,把一條長為8的序列迴圈移動1個單位。
例如下圖最左邊的“#”形棋盤執行操作A後,會變為下圖中間的“#”形棋盤,再執行操作C後會變成下圖最右邊的“#”形棋盤。
給定一個初始狀態,請使用最少的操作次數,使“#”形棋盤最中間的8個格子裡的數字相同。
2286_1.jpg
輸入格式
輸入包含多組測試用例。
每個測試用例佔一行,包含24個數字,表示將初始棋盤中的每一個位置的數字,按整體從上到下,同行從左到右的順序依次列出。
輸入樣例中的第一個測試用例,對應上圖最左邊棋盤的初始狀態。
當輸入只包含一個“0”的行時,表示輸入終止。
輸出格式
每個測試用例輸出佔兩行。
第一行包含所有移動步驟,每步移動用大寫字母“A~G”中的一個表示,字母之間沒有空格,如果不需要移動則輸出“No moves needed”。
第二行包含一個整數,表示移動完成後,中間8個格子裡的數字。
如果有多種方案,則輸出字典序最小的解決方案。
輸入樣例:
1 1 1 1 3 2 3 2 3 1 3 2 2 3 1 2 2 2 3 1 2 1 3 3
1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3
0
輸出樣例:
AC
2
DDHH
2
思路
搜尋,問最小步數,可以想到bfs和ida,那麼我們考慮使用ida
程式碼實現
#include<cstdio> #include<iostream> #include<algorithm> #include<queue> #include<cstring> #include<cmath> #include<stack> using namespace std; const int maxn=24; int option[8][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 opposite[8]={5,4,7,6,1,0,3,2}; int center[8]={6,7,8,11,12,15,16,17}; int q[maxn]; int path[100]; int f () { static int sum[4]; memset (sum,0,sizeof (sum)); for (int i=0;i<8;i++) { sum[q[center[i]]]++; } int s=0; for (int i=1;i<=3;i++) { s=max (s,sum[i]); } return 8-s; } bool check () { for (int i=0;i<8;i++) if (q[center[i]]!=q[center[0]]) return false; return true; } void oper (int x) { int t=q[option[x][0]]; for (int i=0;i<6;i++) q[option[x][i]]=q[option[x][i+1]]; q[option[x][6]]=t; } bool dfs (int deep,int maxdeep,int last) { if (deep+f()>maxdeep) return false; if (check ()) return true; for (int i=0;i<8;i++) { if (opposite[i]==last) continue; oper (i); path[deep]=i; if (dfs (deep+1,maxdeep,i)) return true; oper (opposite[i]); } return false; } int main () { while (cin>>q[0]&&q[0]) { for (int i=1;i<maxn;i++) { cin>>q[i]; } int deepth=0; while (!dfs (0,deepth,-1)) deepth++; if (!deepth) cout<<"No moves needed"; else { for (int i=0;i<deepth;i++) printf ("%c",path[i]+'A'); } printf ("\n%d\n",q[6]); } return 0; }