[藍橋杯2017初賽]跳蚱蜢


題目鏈接:http://oj.ecustacm.cn/problem.php?id=1318

 

題目描述

如圖所示: 有9只盤子,排成1個圓圈。其中8只盤子內裝着8只蚱蜢,有一個是空盤。

我們把這些蚱蜢順時針編號為 1~8。每只蚱蜢都可以跳到相鄰的空盤中,也可以再用點力,越過一個相鄰的蚱蜢跳到空盤中。
請你計算一下,如果要使得蚱蜢們的隊形改為按照逆時針排列,並且保持空盤的位置不變(也就是1-8換位,2-7換位,...),至少要經過多少次跳躍? 

輸出

輸出一個整數表示答案

 

 

思路:

1、 可以將空盤子看成9的盤子,我們利用狀態壓縮的思想,把盤子剛開始的狀態定義成: 123456789 , 那么最后盤子逆序后的狀態就應該為 876543219 ,螞蚱可以跳一個格子和兩個格子,那么螞蚱的跳躍距離就是|2|距離  
2、 我們可以用滾動數組的方法來使盤子可以左右移動 [(x+9)%9]
3、 然后進行廣搜就可以了。

 

#include <iostream>
#include <algorithm>
#include <string>
#include <string.h>
#include <vector>
#include <map>
#include <stack>
#include <set>
#include <queue>
#include <math.h>
#include <cstdio>
#include <iomanip>
#include <time.h>

#define LL long long
#define INF 0x3f3f3f3f
#define ls nod<<1
#define rs (nod<<1)+1

const int maxn = 1e9 + 10 ;
const LL mod = 20010905;

int st = 123456789,ed = 876543219;
int dir[4] = {1,-1,-2,2};
bool vis[maxn];
int a[10];

int getnum() {
    int sum = 0;
    for (int i = 0;i < 9;i++) {
        sum *= 10;
        sum += a[i];
    }
    return sum;
}

void bfs() {
    std::queue<std::pair<int,int> > q;
    memset(vis,0, sizeof(vis));
    q.push(std::make_pair(st,0));
    while (!q.empty()) {
        int x = q.front().first;
        int step = q.front().second;
        q.pop();
        if (vis[x])
            continue;
        vis[x] = true;
        if (x == ed) {
            printf("%d\n",step);
            return ;
        }
        int j = 8,now;
        while (x) {
            if (x % 10 == 9)
                now = j;
            a[j--] = x % 10;
            x /= 10;
        }
        for (int i = 0;i < 4;i++) {
            std::swap(a[now],a[(now+dir[i]+9)%9]);
            int val = getnum();
            if (!vis[val]) {
                q.push(std::make_pair(val,step+1));
            }
            std::swap(a[now],a[(now+dir[i]+9)%9]);
        }
    }
}

int main() {
    bfs();
    return 0;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM