2017第八届蓝桥杯省赛-大学A组 跳蚱蜢(广搜BFS+状态压缩)

描述

如图 p1.png 所示:
这里写图片描述
有9只盘子,排成1个圆圈。 其中8只盘子内装着8只蚱蜢,有一个是空盘。 我们把这些蚱蜢顺时针编号为 1~8

每只蚱蜢都可以跳到相邻的空盘中, 也可以再用点力,越过一个相邻的蚱蜢跳到空盘中。

请你计算一下,如果要使得蚱蜢们的队形改为按照逆时针排列,
并且保持空盘的位置不变(也就是1-8换位,2-7换位,…),至少要经过多少次跳跃?

注意:要求提交的是一个整数,请不要填写任何多余内容或说明文字。

思路

这个题需要注意以下几点:

  1. 可以将空盘子看成0或者9的盘子,我们利用状态压缩的思想,把盘子刚开始的状态定义成:123456789,那么最后盘子逆序后的状态就应该为876543219,蚂蚱可以跳一个格子和两个格子,那么蚂蚱的跳跃距离就是|2|距离,
  2. 我们可以用滚动数组的方法来使盘子可以左右移动[(x+9)%9]
  3. 然后进行广搜就可以了。

代码

#include 
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
#define pir pair
const int N=1e9+10;
bool vis[N];
int st=123456789,ed=876543219;
int go[4]= {-2,-1,1,2},a[10];
int get_num()
{
    int sum=0;
    for(int i=0; i<9; i++)
    {
        sum*=10;
        sum+=a[i];
    }
    return sum;
}
int main()
{
    queueq;
    mem(vis,0);
    q.push(make_pair(st,0));//pair中存的是当前状态和所需步数
    vis[st]=1;
    while(!q.empty())
    {
        int x=q.front().first,step=q.front().second;
        int cnt=8,now;
        q.pop();
        while(x)
        {
            if(x%10==9)
                now=cnt;//找到当前空位的位置
            a[cnt--]=x%10;//把当前状态存进a数组
            x/=10;
        }
        for(int i=0; i<4; i++)
        {
            swap(a[now],a[(now+go[i]+9)%9]);
            int val=get_num();
            if(!vis[val])
            {
                vis[val]=1;
                if(val==ed)
                {
                    printf("ans=%d\n",step+1);
                    return 0;
                }
                q.push(make_pair(val,step+1));
            }
            swap(a[now],a[(now+go[i]+9)%9]);
        }
    }
    return 0;
}

你可能感兴趣的:(【蓝桥杯】,【搜索(DFS/BFS)】)