luogu#P1379 八数码难题

Posted nent

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了luogu#P1379 八数码难题相关的知识,希望对你有一定的参考价值。

题意:

在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字。棋盘中留有一个空格,空格用0来表示。空格周围的棋子可以移到空格中。要求解的问题是:给出一种初始布局(初始状态)和目标布局(为了使题目简单,设目标状态为123804765),找到一种最少步骤的移动方法,实现从初始布局到目标布局的转变。

解法:

A*

#include<iostream>
#include<queue>
#include<map>
#define END 123804765

using namespace std;
struct node
{
    int now,step,g;
    bool operator < (const node &x)const 
    {
        return x.g<g;   
    }
};

int end[9]={1,2,3,8,0,4,7,6,5};
int a[9];
priority_queue<node> q;
node tmp;

map<int,int> m;


inline int fnd(int x);
inline int abs(int x);
void in();
void move(int i,int t);
void out(int x);
int g(int now,int step);
int main()
{
    int s;

    cin>>s; 
    tmp.now=s; tmp.step=0; tmp.g=0; 
    q.push(tmp);
    
    while(1)
    {
        int x;
        tmp=q.top(); q.pop();
        
        if(m.count(tmp.now))
            continue;
        m[tmp.now]=1;
        
    
        if(tmp.now==END)
        {
            cout<<tmp.step;
            return 0;
        }
        out(tmp.now);
        
        
        for(int i=0;i<9;i++)
            if(!a[i])
            {
                x=i;
                break;
            }
        
        
        if((x+1)%3) //right
            move(x,1);
        if(x%3) //left
            move(x,-1);
        if(x>=0&&x<=5) //up
            move(x,3);
        if(x>=3&&x<=8) //down
            move(x,-3); 
    
    }   
    return 0;
}
int g(int x,int step)
{
    int ans=step*2;
    for(int i=0;i<9;i++)
        ans+=abs(fnd(a[i])-i);
    return ans;
}
void out(int x)
{
    for(int i=8;i>=0;i--)
    {
        a[i]=x%10;
        x/=10;
    }
}
void move(int i,int t)
{
    if(i+t<=8&&i+t>=0)
    {
        swap(a[i],a[i+t]);
        in();
        swap(a[i],a[i+t]);
    }
}
void in()
{
    int ans=0;
    for(int i=0;i<9;i++)
        ans=ans*10+a[i];
    node z;
    z.step=tmp.step+1; z.now=ans;
    z.g=g(ans,z.step);
    //m[ans]=1;
    q.push(z);
}
inline int abs(int x)
{
    return x>0?x:-1;
}
inline int fnd(int x)
{
    switch(x)
    {
        case 1 : return 0;
        case 2 : return 1;
        case 3 : return 2;
        case 4 : return 5;
        case 5 : return 8;
        case 6 : return 7;
        case 7 : return 6;
        case 8 : return 3;
        case 0 : return 4;
    }
}

以上是关于luogu#P1379 八数码难题的主要内容,如果未能解决你的问题,请参考以下文章

P1379 八数码难题

luogu_1379 八数码难题

luogu P1379 八数码难题

洛谷P1379八数码难题

洛谷 P1379 八数码难题 Label:判重&&bfs

题解 P1379 八数码难题