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

魔板 Magic Squares

时间:2018-10-04 23:58:01      阅读:353      评论:0      收藏:0      [点我收藏+]

标签:cpp   实现   拓展   www   根据   目标   step   class   new   

【题目描述】:
魔板 Magic Squares

【思路】:
是不是感觉和八数码有点像?
显而易见的宽搜,把魔板的状态表示为排列,则状态最多有\(8! = 40320\)种,空间是可以接受的,对于是第几个排列可以用康拓展开来实现(我想在做八数码的时候你们都深知这个套路),然后根据题目中的三种方式转移状态,每个状态转移出\(3\)个子状态,注意判重!,一旦目标状态出现,那个所搜索的层数一定是能得到该状态的最小步数。最后就是代码细节多,要仔细。

#include<cstdio>
#include<queue>
#include<algorithm>
using namespace std;
int calc[]={1,1,2,6,24,120,720,5040};

int mp[3][5];
bool vis[45000];int rest[10];int a[45000][10];int ans;int Ans;int step[45000];int st;
char last[45000];char endd[45000];int fa[45000];

inline bool judge(){//康拓展开标记 
    ans = 0;int id = 7;
    for(int i=1;i<=8;++i) rest[i] = i-1;
    for(int i=1;i<=4;++i){
        ans += (rest[mp[1][i]]) * calc[id];
        for(int j=mp[1][i]+1;j<=8;++j) rest[j]--;
        id--;
    }
    for(int i=1;i<4;++i){
        ans += (rest[mp[2][i]]) * calc[id];
        for(int j=mp[2][i]+1;j<=8;++j) rest[j]--;
        id--;
    }
    ans++;
    if(vis[ans]){
        if(ans == Ans) return 1;
        else return 0;
    }
    vis[ans] = 1;
    id = 0;
    for(int i=1;i<=4;++i) a[ans][++id] = mp[1][i];
    for(int i=1;i<=4;++i) a[ans][++id] = mp[2][i];
    return 1;
}

inline bool A(int x){
    int id = 0;
    for(int i=1;i<=4;++i) mp[1][i] = a[x][++id];
    for(int i=1;i<=4;++i) mp[2][i] = a[x][++id];
    swap(mp[1] , mp[2]);
    return judge();
}

inline bool B(int x){
    int id = 0;
    for(int i=1;i<=4;++i) mp[1][i] = a[x][++id];
    for(int i=1;i<=4;++i) mp[2][i] = a[x][++id];
    swap(mp[1][4] , mp[1][1]);
    swap(mp[2][4] , mp[2][1]);
    for(int i=4;i>=3;--i){
        swap(mp[1][i] , mp[1][i-1]);
        swap(mp[2][i] , mp[2][i-1]);
    }
    return judge();
}

inline bool C(int x){
    int id = 0;
    for(int i=1;i<=4;++i) mp[1][i] = a[x][++id];
    for(int i=1;i<=4;++i) mp[2][i] = a[x][++id];
    swap(mp[1][2] , mp[1][3]);
    swap(mp[1][2] , mp[2][2]);
    swap(mp[2][2] , mp[2][3]);
    return judge();
}

queue<int>q;
inline void bfs(){
    q.push(st);
    while(!q.empty()){
        int u = q.front();q.pop();
        if(A(u)){
            q.push(ans),step[ans] = step[u] + 1;
            last[ans] = 'A';fa[ans] = u;
            if(ans == Ans){printf("%d\n",step[ans]);return ;}
        }
        if(B(u)){
            q.push(ans),step[ans] = step[u] + 1;
            last[ans] = 'B';fa[ans] = u;
            if(ans == Ans){printf("%d\n",step[ans]);return ;}
        }
        if(C(u)){
            q.push(ans),step[ans] = step[u] + 1;
            last[ans] = 'C';fa[ans] = u;
            if(ans == Ans){printf("%d\n",step[ans]);return ;}
        }
    }
}

int main(){
    for(int i=1;i<=4;++i) mp[1][i] = i;
    for(int i=1;i<=4;++i) mp[2][i] = 9 - i;
    judge();st = ans;last[st] = '&';
    for(int i=1;i<=4;++i) a[Ans][i] = i;
    for(int i=5;i<=8;++i) a[Ans][i] = 13-i; 
    for(int i=1;i<=4;++i) scanf("%d",&mp[1][i]);
    for(int i=1;i<=4;++i) scanf("%d",&mp[2][5-i]);
    judge();Ans = ans;
    if(st == Ans){
        puts("0");
        return 0;
    }
    bfs();
    int x = Ans;int num = 0;
    while(last[x] != '&'){
        endd[++num] = last[x];
        x = fa[x];
    }
    for(int i=num;i>=1;--i) printf("%c",endd[i]);
    return 0;
}

魔板 Magic Squares

标签:cpp   实现   拓展   www   根据   目标   step   class   new   

原文地址:https://www.cnblogs.com/lajioj/p/9743758.html

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