【習題 7-9 UVA-1604】Cubic Eight-Puzzle
阿新 • • 發佈:2018-01-01
推出 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