www 被大佬们吊打|

wscqwq

园龄:2年粉丝:2关注:3

my

八数码问题

A 算法例题。

首先判断是否有解。这里有一个条件:将八数码转化为序列后如果逆序对数为偶数,一定有解,否则一定无解。

充分性难证明,只证明必要性:只要是有解必定是偶数。

行内移动序列没有变,数量不变。

如果上下移动发现逆序对变化是 [0,±2]

而答案序列逆序对为 0,为偶数。先证明到这里。。。

显然估价函数应该设置为所有数与它目标位置之间的曼哈顿距离之和,因为每次最多只能将一个数向目标位置靠近,而且一般不能达到最好的情况。

#include<bits/stdc++.h>
using namespace std;
#define f first
#define s second
typedef pair<int,string> PIS;
int f(string state){
    int res=0;
    for(int i=0;i<state.size();++i){
        int t=state[i]-49;
        res+=abs(i/3-t/3)+abs(i%3-t%3);
    }
    return res;
}
string bfs(string start){
    const int dx[]={-1,1,0,0},dy[]={0,0,-1,1};
    string op="udlr";
    string end="12345678x";
    unordered_map<string,int>dist;
    unordered_map<string,pair<string,char>>prev;
    priority_queue<PIS,vector<PIS>,greater<PIS>>heap;
    heap.push({f(start),start});
    dist[start]=0;
    while(!heap.empty()){
        auto t=heap.top();
        heap.pop();
        string state=t.s;
        if(state==end)break;
        int step=dist[state];
        int x,y;
        for(int i=0;i<state.size();++i)
            if(state[i]=='x'){
                x=i/3,y=i%3;
                break;
            }
        string source=state;
        for(int i=0;i<4;++i){
            state=source;
            int a=x+dx[i],b=y+dy[i];
            if(a>=0&&a<3&&b>=0&&b<3){
                swap(state[x*3+y],state[a*3+b]);
                if(!dist.count(state)||dist[state]>step+1){
                    dist[state]=step+1;
                    prev[state]={source,op[i]};
                    heap.push({dist[state]+f(state),state});
                }
            }
        }
    }
    string res;
    while(end!=start){
        res+=prev[end].s;
        end=prev[end].f;
    }
    reverse(res.begin(),res.end());
    return res;
}
int main(){
    string g,seq;
    char c;
    while(cin>>c){
        g+=c;
        if(c!='x')seq+=c;
    }
    int t=0;
    for(int i=0;i<8;++i)
        for(int j=i+1;j<8;++j)
            if(seq[i]>seq[j])++t;
    if(t&1)puts("unsolvable");
    else puts(bfs(g).c_str());
    return 0;
}

本文作者:wscqwq

本文链接:https://www.cnblogs.com/wscqwq/p/17393799.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   wscqwq  阅读(17)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起