1. 程式人生 > >【習題 7-9 UVA-1604】Cubic Eight-Puzzle

【習題 7-9 UVA-1604】Cubic Eight-Puzzle

推出 other dep long long span -m pen mar 多少

【鏈接】 我是鏈接,點我呀:)
【題意】


在這裏輸入題意

【題解】


IDA*
保證這次移動的方格不和前一次重復。
然後加一個8數碼的剪枝就行了。
->看看當前狀態和目標狀態有多少個地方是不一樣的。
如果當前的步數加上它仍然比答案大。
顯然可以剪枝。
因為不同的數目肯定小於等於要移動的數目;
(每次移動最多只能讓一個方格還原)

(然後只要記錄上面和前面的顏色就好了
剩下一個面的顏色能夠通過其他兩種顏色推出來。
對面的顏色是相等的。

(這個算法(剪枝)的效率真的超級高。。。

【代碼】

#include <bits/stdc++.h>
#define ll long long
using namespace std; //上 前 //0 1 //0 1 2 3 //E B W R const int dx[4] = {-1,1,0,0}; const int dy[4] = {0,0,1,-1}; pair<int,int> a[5][5]; int goal[5][5],ans; int other(int x,int y){ return 6-(x+y); } void rotate_left_right(pair<int,int> &x){ pair<ll,ll> temp = x; x.first = other(temp.first,temp.second); x.second = temp.second; } void
rotate_up_down(pair<int,int> &x){ pair<ll,ll> temp = x; x.first = temp.second; x.second = temp.first; } int gujia(){ int cnt = 0; for (int i = 1;i <= 3;i++) for (int j = 1;j <= 3;j++) if (a[i][j].first!=goal[i][j]) cnt++; return
cnt; } void dfs(int dep,int prex,int prey){ int differ = gujia(); if (differ==0){ if (dep < ans){ ans = dep; return; } return; } if (dep + differ>ans) return; int x,y; for (int i = 1;i <= 3;i++) for (int j = 1;j <= 3;j++) if (a[i][j].first==0){ x = i,y = j; } for (int i = 0;i < 4;i++){ int tx = x + dx[i],ty = y + dy[i]; if (tx >=1 && tx<=3 && ty>=1 && ty <= 3 &&!(tx==prex && ty==prey)) { pair<int,int> temp = a[tx][ty]; if (i>1) rotate_left_right(a[tx][ty]); else rotate_up_down(a[tx][ty]); swap(a[tx][ty],a[x][y]); dfs(dep+1,x,y); a[tx][ty] = temp; a[x][y] = {0,0}; } } } int main(){ #ifdef LOCAL_DEFINE freopen("rush_in.txt", "r", stdin); #endif ios::sync_with_stdio(0),cin.tie(0); int x,y; while (cin >> x >> y){ swap(x,y); if (x==0 && y==0) break; for (int i = 1;i<=3;i++) for (int j = 1;j<= 3;j++){ if (i==x && y==j) a[i][j] = {0,0}; else a[i][j] = {2,3}; } for (int i = 1;i <= 3;i++) for (int j = 1;j <= 3;j++){ char s[3]; cin >> s; goal[i][j] = 0; switch(s[0]){ case 'B':goal[i][j] = 1;break; case 'W':goal[i][j] = 2;break; case 'R':goal[i][j] = 3;break; } } ans = 31; dfs(0,-1,-1); if (ans>=31){ cout << -1 << endl; }else{ cout << ans << endl; } } return 0; }

【習題 7-9 UVA-1604】Cubic Eight-Puzzle