1. 程式人生 > >luogu P1379 八數碼難題

luogu P1379 八數碼難題

測試數據 ret %d -c opp ron line star 數碼

題目描述

在3×3的棋盤上,擺有八個棋子,每個棋子上標有1至8的某一數字。棋盤中留有一個空格,空格用0來表示。空格周圍的棋子可以移到空格中。要求解的問題是:給出一種初始布局(初始狀態)和目標布局(為了使題目簡單,設目標狀態為123804765),找到一種最少步驟的移動方法,實現從初始布局到目標布局的轉變。

輸入輸出格式

輸入格式:

輸入初始狀態,一行九個數字,空格用0表示

輸出格式:

只有一行,該行只有一個數字,表示從初始狀態到目標狀態需要的最少移動次數(測試數據中無特殊無法到達目標狀態數據)

輸入輸出樣例

輸入樣例#1:
283104765
輸出樣例#1:
4

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <map>
#include <queue>
#include <cstring>
#include <string> 

using namespace std;
const string s_end = "123804765";

struct Node{
    string s;
    
int step; }; queue <Node> Q1; map <string, bool> mp; string s_start; int Step; inline void pd(string ss, int answer) { if(ss == s_end) { printf("%d",answer); exit(0); } } inline void bfs() { while(!Q1.empty()) { Node topp = Q1.front(); Q1.pop();
string s1 = topp.s; Step = topp.step; int f = s1.find(0); Node nxt; if(f == 0) { swap(s1[0], s1[1]);pd(s1, topp.step + 1); if(!mp[s1]){nxt.s = s1;nxt.step = topp.step + 1;Q1.push(nxt);mp[s1] = 1; } swap(s1[0], s1[1]); swap(s1[0], s1[3]);pd(s1, topp.step + 1); if(!mp[s1]){nxt.s = s1;nxt.step = topp.step + 1;Q1.push(nxt);mp[s1] = 1; }continue; } if(f == 1) { swap(s1[0], s1[1]);pd(s1, topp.step + 1); if(!mp[s1]){nxt.s = s1;nxt.step = topp.step + 1;Q1.push(nxt);mp[s1] = 1; }swap(s1[0], s1[1]); swap(s1[1], s1[2]);pd(s1, topp.step + 1); if(!mp[s1]){nxt.s = s1;nxt.step = topp.step + 1;Q1.push(nxt);mp[s1] = 1; }swap(s1[1], s1[2]); swap(s1[1], s1[4]);pd(s1, topp.step + 1); if(!mp[s1]){nxt.s = s1;nxt.step = topp.step + 1;Q1.push(nxt);mp[s1] = 1; }continue; } if(f == 2) { swap(s1[1], s1[2]);pd(s1, topp.step + 1); if(!mp[s1]){nxt.s = s1;nxt.step = topp.step + 1;Q1.push(nxt);mp[s1] = 1; }swap(s1[1], s1[2]); swap(s1[2], s1[5]);pd(s1, topp.step + 1); if(!mp[s1]){nxt.s = s1;nxt.step = topp.step + 1;Q1.push(nxt);mp[s1] = 1; }continue; } if(f == 3) { swap(s1[0], s1[3]);pd(s1, topp.step + 1); if(!mp[s1]){nxt.s = s1;nxt.step = topp.step + 1;Q1.push(nxt);mp[s1] = 1; }swap(s1[0], s1[3]); swap(s1[3], s1[4]);pd(s1, topp.step + 1); if(!mp[s1]){nxt.s = s1;nxt.step = topp.step + 1;Q1.push(nxt);mp[s1] = 1; }swap(s1[3], s1[4]); swap(s1[3], s1[6]);pd(s1, topp.step + 1); if(!mp[s1]){nxt.s = s1;nxt.step = topp.step + 1;Q1.push(nxt);mp[s1] = 1; }continue; } if(f == 4) { swap(s1[1], s1[4]);pd(s1, topp.step + 1); if(!mp[s1]){nxt.s = s1;nxt.step = topp.step + 1;Q1.push(nxt);mp[s1] = 1; }swap(s1[1], s1[4]); swap(s1[3], s1[4]);pd(s1, topp.step + 1); if(!mp[s1]){nxt.s = s1;nxt.step = topp.step + 1;Q1.push(nxt);mp[s1] = 1; }swap(s1[3], s1[4]); swap(s1[5], s1[4]);pd(s1, topp.step + 1); if(!mp[s1]){nxt.s = s1;nxt.step = topp.step + 1;Q1.push(nxt);mp[s1] = 1; }swap(s1[5], s1[4]); swap(s1[7], s1[4]);pd(s1, topp.step + 1); if(!mp[s1]){nxt.s = s1;nxt.step = topp.step + 1;Q1.push(nxt);mp[s1] = 1; }continue; } if(f == 5) { swap(s1[5], s1[2]);pd(s1, topp.step + 1); if(!mp[s1]){nxt.s = s1;nxt.step = topp.step + 1;Q1.push(nxt);mp[s1] = 1; }swap(s1[5], s1[2]); swap(s1[5], s1[4]);pd(s1, topp.step + 1); if(!mp[s1]){nxt.s = s1;nxt.step = topp.step + 1;Q1.push(nxt);mp[s1] = 1; }swap(s1[5], s1[4]); swap(s1[5], s1[8]);pd(s1, topp.step + 1); if(!mp[s1]){nxt.s = s1;nxt.step = topp.step + 1;Q1.push(nxt);mp[s1] = 1; }continue; } if(f == 6) { swap(s1[6], s1[3]);pd(s1, topp.step + 1); if(!mp[s1]){nxt.s = s1;nxt.step = topp.step + 1;Q1.push(nxt);mp[s1] = 1; }swap(s1[6], s1[3]); swap(s1[6], s1[7]);pd(s1, topp.step + 1); if(!mp[s1]){nxt.s = s1;nxt.step = topp.step + 1;Q1.push(nxt);mp[s1] = 1; }continue; } if(f == 7) {//4 7 6 7 8 7 swap(s1[4], s1[7]);pd(s1, topp.step + 1); if(!mp[s1]){nxt.s = s1;nxt.step = topp.step + 1;Q1.push(nxt);mp[s1] = 1; }swap(s1[4], s1[7]); swap(s1[6], s1[7]);pd(s1, topp.step + 1); if(!mp[s1]){nxt.s = s1;nxt.step = topp.step + 1;Q1.push(nxt);mp[s1] = 1; }swap(s1[6], s1[7]); swap(s1[8], s1[7]);pd(s1, topp.step + 1); if(!mp[s1]){nxt.s = s1;nxt.step = topp.step + 1;Q1.push(nxt);mp[s1] = 1; }continue; } if(f == 8) {//58 78 swap(s1[5], s1[8]);pd(s1, topp.step + 1); if(!mp[s1]){nxt.s = s1;nxt.step = topp.step + 1;Q1.push(nxt);mp[s1] = 1; }swap(s1[5], s1[8]); swap(s1[7], s1[8]);pd(s1, topp.step + 1); if(!mp[s1]){nxt.s = s1;nxt.step = topp.step + 1;Q1.push(nxt);mp[s1] = 1;}continue; } } } int main() { cin >> s_start; Node now; now.s = s_start; now.step = 0; Q1.push(now); bfs(); return 0; } //283104765

雙向bfs竟然超時

// 雙向 bfs 
/*
    是否已經被正向搜到了,且用了多少步  map <string, int> is_front;  註意,這個map只存儲正向搜到的狀態 
    正反兩個隊列
    分別存儲當前狀態以及所用步數
    正反交替進行
        每當反向搜到 map[當前狀態] != 0 時, answer = map[當前狀態] + 反向搜到的步數 
*/
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <map>
#include <queue>
#include <cstring>
#include <string> 

using namespace std;
const string s_end = "123804765";

struct Node{
    string s;
    int step;
};

string s_start;
queue <Node> Q1;
queue <Node> Q2;
map <string, int> mp;
map <string, int> mp_back;

inline void pd(string ss, int answer){if(ss == s_end){printf("%d", answer);exit(0);}}
inline void pd_out(int a, int answer, string ss){if(a){printf("%d",answer);exit(0);}}
void bfs_front();

inline void bfs_back() 
{
    while(1)
    {
        Node topp = Q2.front();
        Q2.pop();
        string now = topp.s;
        int f = now.find(0);
        string s1 = now;
        Node nxt;
        if(f == 0)
        {
            swap(s1[0], s1[1]);pd_out(mp[s1], topp.step + mp[s1] + 1, s1);
            if(!mp_back[s1]){nxt.s = s1;nxt.step = topp.step + 1;Q2.push(nxt);mp_back[s1] = nxt.step;}swap(s1[0], s1[1]); 
            swap(s1[0], s1[3]); pd_out(mp[s1], topp.step + mp[s1] + 1, s1);
            if(!mp_back[s1]){nxt.s = s1;nxt.step = topp.step + 1;Q2.push(nxt);mp_back[s1] = nxt.step;}continue;
        }
        if(f == 1)
        {
            swap(s1[0], s1[1]); pd_out(mp[s1], topp.step + mp[s1] + 1, s1);
            if(!mp_back[s1]){nxt.s = s1;nxt.step = topp.step + 1;Q2.push(nxt);mp_back[s1] = nxt.step;}swap(s1[0], s1[1]);
            swap(s1[1], s1[2]); pd_out(mp[s1], topp.step + mp[s1] + 1, s1);
            if(!mp_back[s1]){nxt.s = s1;nxt.step = topp.step + 1;Q2.push(nxt);mp_back[s1] = nxt.step;}swap(s1[1], s1[2]);
            swap(s1[1], s1[4]); pd_out(mp[s1], topp.step + mp[s1] + 1, s1);
            if(!mp_back[s1]){nxt.s = s1;nxt.step = topp.step + 1;Q2.push(nxt);mp_back[s1] = nxt.step;}continue;
        }
        if(f == 2)
        {
            swap(s1[1], s1[2]); pd_out(mp[s1], topp.step + mp[s1] + 1, s1);
            if(!mp_back[s1]){nxt.s = s1;nxt.step = topp.step + 1;Q2.push(nxt);mp_back[s1] = nxt.step;}swap(s1[1], s1[2]);
            swap(s1[2], s1[5]); pd_out(mp[s1], topp.step + mp[s1] + 1, s1);
            if(!mp_back[s1]){nxt.s = s1;nxt.step = topp.step + 1;Q2.push(nxt);mp_back[s1] = nxt.step;}continue;
        }
        if(f == 3)
        {
            swap(s1[0], s1[3]); pd_out(mp[s1], topp.step + mp[s1] + 1, s1);
            if(!mp_back[s1]){nxt.s = s1;nxt.step = topp.step + 1;Q2.push(nxt);mp_back[s1] = nxt.step;}swap(s1[0], s1[3]);
            swap(s1[3], s1[4]); pd_out(mp[s1], topp.step + mp[s1] + 1, s1);
            if(!mp_back[s1]){nxt.s = s1;nxt.step = topp.step + 1;Q2.push(nxt);mp_back[s1] = nxt.step;}swap(s1[3], s1[4]);
            swap(s1[3], s1[6]); pd_out(mp[s1], topp.step + mp[s1] + 1, s1);
            if(!mp_back[s1]){nxt.s = s1;nxt.step = topp.step + 1;Q2.push(nxt);mp_back[s1] = nxt.step;}continue;
        }
        if(f == 4)
        {
            swap(s1[1], s1[4]); pd_out(mp[s1], topp.step + mp[s1] + 1, s1);
            if(!mp_back[s1]){nxt.s = s1;nxt.step = topp.step + 1;Q2.push(nxt);mp_back[s1] = nxt.step;}swap(s1[1], s1[4]);
            swap(s1[3], s1[4]); pd_out(mp[s1], topp.step + mp[s1] + 1, s1);
            if(!mp_back[s1]){nxt.s = s1;nxt.step = topp.step + 1;Q2.push(nxt);mp_back[s1] = nxt.step;}swap(s1[3], s1[4]);
            swap(s1[5], s1[4]); pd_out(mp[s1], topp.step + mp[s1] + 1, s1);
            if(!mp_back[s1]){nxt.s = s1;nxt.step = topp.step + 1;Q2.push(nxt);mp_back[s1] = nxt.step;}swap(s1[5], s1[4]);
            swap(s1[7], s1[4]); pd_out(mp[s1], topp.step + mp[s1] + 1, s1);
            if(!mp_back[s1]){nxt.s = s1;nxt.step = topp.step + 1;Q2.push(nxt);mp_back[s1] = nxt.step;}continue;
        }
        if(f == 5)
        {
            swap(s1[5], s1[2]); pd_out(mp[s1], topp.step + mp[s1] + 1, s1);
            if(!mp_back[s1]){nxt.s = s1;nxt.step = topp.step + 1;Q2.push(nxt);mp_back[s1] = nxt.step;}swap(s1[5], s1[2]);
            swap(s1[5], s1[4]); pd_out(mp[s1], topp.step + mp[s1] + 1, s1);
            if(!mp_back[s1]){nxt.s = s1;nxt.step = topp.step + 1;Q2.push(nxt);mp_back[s1] = nxt.step;}swap(s1[5], s1[4]);
            swap(s1[5], s1[8]); pd_out(mp[s1], topp.step + mp[s1] + 1, s1);
            if(!mp_back[s1]){nxt.s = s1;nxt.step = topp.step + 1;Q2.push(nxt);mp_back[s1] = nxt.step;}continue;
        }
        if(f == 6)
        {
            swap(s1[6], s1[3]); pd_out(mp[s1], topp.step + mp[s1] + 1, s1);
            if(!mp_back[s1]){nxt.s = s1;nxt.step = topp.step + 1;Q2.push(nxt);mp_back[s1] = nxt.step;}swap(s1[6], s1[3]);
            swap(s1[6], s1[7]); pd_out(mp[s1], topp.step + mp[s1] + 1, s1);
            if(!mp_back[s1]){nxt.s = s1;nxt.step = topp.step + 1;Q2.push(nxt);mp_back[s1] = nxt.step;}continue;
        }
        if(f == 7)
        {//4 7    6 7    8 7
            swap(s1[4], s1[7]); pd_out(mp[s1], topp.step + mp[s1] + 1, s1);
            if(!mp_back[s1]){nxt.s = s1;nxt.step = topp.step + 1;Q2.push(nxt);mp_back[s1] = nxt.step;}swap(s1[4], s1[7]);
            swap(s1[6], s1[7]); pd_out(mp[s1], topp.step + mp[s1] + 1, s1);
            if(!mp_back[s1]){nxt.s = s1;nxt.step = topp.step + 1;Q2.push(nxt);mp_back[s1] = nxt.step;}swap(s1[6], s1[7]);
            swap(s1[8], s1[7]); pd_out(mp[s1], topp.step + mp[s1] + 1, s1);
            if(!mp_back[s1]){nxt.s = s1;nxt.step = topp.step + 1;Q2.push(nxt);mp_back[s1] = nxt.step;}continue;
        }
        if(f == 8)
        {//58   78
            swap(s1[5], s1[8]); pd_out(mp[s1], topp.step + mp[s1] + 1, s1);
            if(!mp_back[s1]){nxt.s = s1;nxt.step = topp.step + 1;Q2.push(nxt);mp_back[s1] = nxt.step;}swap(s1[5], s1[8]);
            swap(s1[7], s1[8]); pd_out(mp[s1], topp.step + mp[s1] + 1, s1);
            if(!mp_back[s1]){nxt.s = s1;nxt.step = topp.step + 1;Q2.push(nxt);mp_back[s1] = nxt.step;}continue;
        }
        return ;
    }
}

inline void bfs_front()//正向 bfs 
{
    while(1)
    {
        Node topp = Q1.front();
        Q1.pop();
        string now = topp.s;
        int f = now.find(0);
        Node nxt;
        string s1 = now;
        if(f == 0)
        {
            swap(s1[0], s1[1]);pd(s1, topp.step + 1);pd_out(mp_back[s1], topp.step + mp_back[s1] + 1, s1);
            if(!mp[s1]){nxt.s = s1;nxt.step = topp.step + 1;Q1.push(nxt);mp[s1] = nxt.step;}swap(s1[0], s1[1]);
            swap(s1[0], s1[3]);pd(s1, topp.step + 1);pd_out(mp_back[s1], topp.step + mp_back[s1] + 1, s1);
            if(!mp[s1]){nxt.s = s1;nxt.step = topp.step + 1;Q1.push(nxt);mp[s1] = nxt.step;}continue;
        }
        if(f == 1)
        {
            swap(s1[0], s1[1]);pd(s1, topp.step + 1);pd_out(mp_back[s1], topp.step + mp_back[s1] + 1, s1);
            if(!mp[s1]){nxt.s = s1;nxt.step = topp.step + 1;Q1.push(nxt);mp[s1] = nxt.step;}swap(s1[0], s1[1]);
            swap(s1[1], s1[2]);pd(s1, topp.step + 1);pd_out(mp_back[s1], topp.step + mp_back[s1] + 1, s1);
            if(!mp[s1]){nxt.s = s1;nxt.step = topp.step + 1;Q1.push(nxt);mp[s1] = nxt.step;}swap(s1[1], s1[2]);
            swap(s1[1], s1[4]);pd(s1, topp.step + 1);pd_out(mp_back[s1], topp.step + mp_back[s1] + 1, s1);
            if(!mp[s1]){nxt.s = s1;nxt.step = topp.step + 1;Q1.push(nxt);mp[s1] = nxt.step;}continue;
        }
        if(f == 2)
        {
            swap(s1[1], s1[2]);pd(s1, topp.step + 1);pd_out(mp_back[s1], topp.step + mp_back[s1] + 1, s1);
            if(!mp[s1]){nxt.s = s1;nxt.step = topp.step + 1;Q1.push(nxt);mp[s1] = nxt.step;}swap(s1[1], s1[2]);
            swap(s1[2], s1[5]);pd(s1, topp.step + 1);pd_out(mp_back[s1], topp.step + mp_back[s1] + 1, s1);
            if(!mp[s1]){nxt.s = s1;nxt.step = topp.step + 1;Q1.push(nxt);mp[s1] = nxt.step;}continue;
        }
        if(f == 3)
        {
            swap(s1[0], s1[3]);pd(s1, topp.step + 1);pd_out(mp_back[s1], topp.step + mp_back[s1] + 1, s1);
            if(!mp[s1]){nxt.s = s1;nxt.step = topp.step + 1;Q1.push(nxt);mp[s1] = nxt.step;}swap(s1[0], s1[3]);
            swap(s1[3], s1[4]);pd(s1, topp.step + 1);pd_out(mp_back[s1], topp.step + mp_back[s1] + 1, s1);
            if(!mp[s1]){nxt.s = s1;nxt.step = topp.step + 1;Q1.push(nxt);mp[s1] = nxt.step;}swap(s1[3], s1[4]);
            swap(s1[3], s1[6]);pd(s1, topp.step + 1);pd_out(mp_back[s1], topp.step + mp_back[s1] + 1, s1);
            if(!mp[s1]){nxt.s = s1;nxt.step = topp.step + 1;Q1.push(nxt);mp[s1] = nxt.step;}continue;
        }
        if(f == 4)
        {
            swap(s1[1], s1[4]);pd(s1, topp.step + 1);pd_out(mp_back[s1], topp.step + mp_back[s1] + 1, s1);
            if(!mp[s1]){nxt.s = s1;nxt.step = topp.step + 1;Q1.push(nxt);mp[s1] = nxt.step;}swap(s1[1], s1[4]);
            swap(s1[3], s1[4]);pd(s1, topp.step + 1);pd_out(mp_back[s1], topp.step + mp_back[s1] + 1, s1);
            if(!mp[s1]){nxt.s = s1;nxt.step = topp.step + 1;Q1.push(nxt);mp[s1] = nxt.step;}swap(s1[3], s1[4]);
            swap(s1[5], s1[4]);pd(s1, topp.step + 1);pd_out(mp_back[s1], topp.step + mp_back[s1] + 1, s1);
            if(!mp[s1]){nxt.s = s1;nxt.step = topp.step + 1;Q1.push(nxt);mp[s1] = nxt.step;}swap(s1[5], s1[4]);
            swap(s1[7], s1[4]);pd(s1, topp.step + 1);pd_out(mp_back[s1], topp.step + mp_back[s1] + 1, s1);
            if(!mp[s1]){nxt.s = s1;nxt.step = topp.step + 1;Q1.push(nxt);mp[s1] = nxt.step;}continue;
        }
        if(f == 5)
        {
            swap(s1[5], s1[2]);pd(s1, topp.step + 1);pd_out(mp_back[s1], topp.step + mp_back[s1] + 1, s1);
            if(!mp[s1]){nxt.s = s1;nxt.step = topp.step + 1;Q1.push(nxt);mp[s1] = nxt.step;}swap(s1[5], s1[2]);
            swap(s1[5], s1[4]);pd(s1, topp.step + 1);pd_out(mp_back[s1], topp.step + mp_back[s1] + 1, s1);
            if(!mp[s1]){nxt.s = s1;nxt.step = topp.step + 1;Q1.push(nxt);mp[s1] = nxt.step;}swap(s1[5], s1[4]);
            swap(s1[5], s1[8]);pd(s1, topp.step + 1);pd_out(mp_back[s1], topp.step + mp_back[s1] + 1, s1);
            if(!mp[s1]){nxt.s = s1;nxt.step = topp.step + 1;Q1.push(nxt);mp[s1] = nxt.step;}continue;
        }
        if(f == 6)
        {
            swap(s1[6], s1[3]);pd(s1, topp.step + 1);pd_out(mp_back[s1], topp.step + mp_back[s1] + 1, s1);
            if(!mp[s1]){nxt.s = s1;nxt.step = topp.step + 1;Q1.push(nxt);mp[s1] = nxt.step;}swap(s1[6], s1[3]);
            swap(s1[6], s1[7]);pd(s1, topp.step + 1);pd_out(mp_back[s1], topp.step + mp_back[s1] + 1, s1);
            if(!mp[s1]){nxt.s = s1;nxt.step = topp.step + 1;Q1.push(nxt);mp[s1] = nxt.step;}continue;
        }
        if(f == 7)
        {//4 7    6 7    8 7
            swap(s1[4], s1[7]);pd(s1, topp.step + 1);pd_out(mp_back[s1], topp.step + mp_back[s1] + 1, s1);
            if(!mp[s1]){nxt.s = s1;nxt.step = topp.step + 1;Q1.push(nxt);mp[s1] = nxt.step;}swap(s1[4], s1[7]);
            swap(s1[6], s1[7]);pd(s1, topp.step + 1);pd_out(mp_back[s1], topp.step + mp_back[s1] + 1, s1);
            if(!mp[s1]){nxt.s = s1;nxt.step = topp.step + 1;Q1.push(nxt);mp[s1] = nxt.step;}swap(s1[6], s1[7]);
            swap(s1[8], s1[7]);pd(s1, topp.step + 1);pd_out(mp_back[s1], topp.step + mp_back[s1] + 1, s1);
            if(!mp[s1]){nxt.s = s1;nxt.step = topp.step + 1;Q1.push(nxt);mp[s1] = nxt.step;}continue;
        }
        if(f == 8)
        {//58   78
            swap(s1[5], s1[8]);pd(s1, topp.step + 1);pd_out(mp_back[s1], topp.step + mp_back[s1] + 1, s1);
            if(!mp[s1]){nxt.s = s1;nxt.step = topp.step + 1;Q1.push(nxt);mp[s1] = nxt.step;}swap(s1[5], s1[8]);
            swap(s1[7], s1[8]);pd(s1, topp.step + 1);pd_out(mp_back[s1], topp.step + mp_back[s1] + 1, s1);
            if(!mp[s1]){nxt.s = s1;nxt.step = topp.step + 1;Q1.push(nxt);mp[s1] = nxt.step;}continue;
        }
        bfs_back();
    }
    
}
 
int main()
{
    cin >> s_start;Node now;now.s = s_start; now.step = 0;Q1.push(now);
    now.s = s_end;Q2.push(now);
    bfs_front();
    return 0;
}
//283104765
//273645801
//15 
//103824765
//120843765
//123805746

luogu P1379 八數碼難題