• 魔板 Magic Squares


    【题目描述】:
    魔板 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
    ",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
    ",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
    ",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;
    }
    
  • 相关阅读:
    项目数据分析师CPDA印章
    一点想法
    该减肥啦
    PMP证书到手
    Google App Engine之初体验
    转K线理论初级三
    黄小琥没那么简单
    使用webapp框架再现Hello World
    Google App Engine之介绍篇
    转股票中KDJ线的详细分析
  • 原文地址:https://www.cnblogs.com/lajioj/p/9743758.html
Copyright © 2020-2023  润新知