码迷,mamicode.com
首页 > 其他好文 > 详细

【习题 7-9 UVA-1604】Cubic Eight-Puzzle

时间:2018-01-01 20:39:01      阅读:143      评论:0      收藏:0      [点我收藏+]

标签:通过   namespace   down   mes   a*   ifd   logs   wap   i++   

【链接】 我是链接,点我呀:)
【题意】


在这里输入题意

【题解】


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

标签:通过   namespace   down   mes   a*   ifd   logs   wap   i++   

原文地址:https://www.cnblogs.com/AWCXV/p/8168622.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!