1. 程式人生 > 實用技巧 >P1379 八數碼難題(雙端佇列)

P1379 八數碼難題(雙端佇列)

P1379八數碼難題

雙端佇列

用單佇列實現雙端佇列時需要注意標記陣列是不一樣的。我們讓我們想要的第一個佇列用\(1\)來標記,第二個用\(2\)來標記,那麼當他們碰面的時候也就是\(1+2=3\)的時候就是我們想要的答案。

  • 雙端佇列開陣列來記錄權值。

  • 標記要標記傳標記\(vis[now] = vis[cur];\)

  • 雙端佇列對走過點的判斷條件是\(vis\)相同。

思路

\(3\times 3\)陣列化為一位陣列來儲存,移動的時候再轉換為\(3\times 3\)陣列。

需要特判還沒入隊就相等的情況。

交換後記得交換回來。

如果這個點和\(cur\)\(vis\)相同記得換回地圖(\(swap\)

),因為這個點已經走過了。

#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
#define DOF 0x7f7f7f7f
#define endl '\n'
#define mem(a, b) memset(a, b, sizeof(a))
#define debug(case, x) cout << case << "  : " << x << endl
#define open freopen("ii.txt", "r", stdin)
#define close freopen("oo.txt", "w", stdout)
#define IO                       \
    ios::sync_with_stdio(false); \
    cin.tie(0);                  \
    cout.tie(0)
#define pb push_back
using namespace std;
#define int long long
#define lson rt << 1
#define rson rt << 1 | 1
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<long long, long long> PII;
const int maxn = 1e6 + 10;

int str;
int dir[4][2] = {1, 0, 0, 1, -1, 0, 0, -1};
int mt[5][5];
map<int,int>dis;
map<int,int>vis;
void bfs() {
    queue<int>q;
    int flag = 123804765;
    if(str==flag){
        cout<<0<<endl;
        return ;
    }
    q.push(str);
    q.push(flag);
    vis[str] = 1;
    vis[flag] = 2;dis[str]=0,dis[flag]=0;
    while(!q.empty()) {
        int now = q.front();
        int cur = now;
        q.pop();
        int sx=1, sy=1;
        for(int i = 3; i >= 1; --i) {
            for(int j = 3; j >= 1; --j) {
                mt[i][j] = now % 10;
                now /= 10;
                if(mt[i][j]==0)sx = i, sy = j;

            }
        }

        for(int i = 0; i < 4; ++i) {
            int xx = sx + dir[i][0], yy = sy + dir[i][1];
            if(xx < 1 || xx > 3 || yy < 1 || yy > 3)continue;
            swap(mt[sx][sy], mt[xx][yy]);
            now = 0;

            for(int j = 1; j <= 3; ++j) {
                for(int i = 1; i <= 3; ++i) {
                    now = now * 10 + mt[j][i];
                }
            }

            if(vis[cur] == vis[now]) {
                swap(mt[sx][sy], mt[xx][yy]);
                continue;
            }
            if(vis[cur] + vis[now] == 3) {
                cout << dis[cur]+dis[now]+1 << endl;
                return ;
            }
            dis[now]=dis[cur]+1;
            vis[now] = vis[cur];
            q.push(now);
            swap(mt[sx][sy],mt[xx][yy]);
        }

    }

}

signed main() {
    cin >> str;
    bfs();

}