2. 标题:跳蚱蜢
有9只盘子,排成1个圆圈。
其中8只盘子内装着8只蚱蜢,有一个是空盘。
我们把这些蚱蜢顺时针编号为 1~8
每只蚱蜢都可以跳到相邻的空盘中,
也可以再用点力,越过一个相邻的蚱蜢跳到空盘中。
请你计算一下,如果要使得蚱蜢们的队形改为按照逆时针排列,
并且保持空盘的位置不变(也就是1-8换位,2-7换位,...),至少要经过多少次跳跃?
注意:要求提交的是一个整数,请不要填写任何多余内容或说明文字。
题目分析:
首先要明确,需要我们回答至少需要经过多少次跳跃的情况,很多情况都是使用bfs广度优先搜索。通过这个地方我们可以知道,但是这题又不是直接敲模板的bfs,我们需要先将这些蚱蜢抽象出来,变成一个数字问题,然后进行bfs。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#include <algorithm>
using namespace std;
const int maxn = 1000000000;
int s = 123456789,t = 876543219;
bool vis[maxn];
int mo[4] = {-2,-1,1,2},a[10];
int getval(int s[])
{
int sum = 0;
for(int i = 8;i >= 0 ;i--)
{
sum = sum * 10; sum += s[i] % 10;
}
//printf("%d",sum);
//getchar();
return sum;
}
void bfs()
{
queue<int>q1;
queue<int>q2;
memset(vis,0,sizeof(vis));
vis[s] = 1;
int cnt = 8;//cnt表示9也就是空盘子在数组中的位置,以0为起点
q1.push(s);
q2.push(0);
int d = 0;
while(!q1.empty())
{
int x = q1.front() ;
d = q2.front() ;
//cout<<x<<endl;
for(int i = 8; i>= 0 ; i--)
{
if(x % 10 == 9)
{
a[i] = x%10;
x = x/ 10;
cnt = i;
}
else
{
a[i] = x%10;
x = x/10;
}
}
for(int i = 0; i < 4; i++)
{
int k = a[(cnt + mo[i] + 9) % 9];
a[(cnt + mo[i]+9) % 9] = a[cnt];
a[cnt] = k;
int val = getval(a);
//cout<<val<<endl;
//getchar();
if(vis[val] == 0)
{
vis[val] = 1;
q1.push(val);
q2.push(d+1);
if(val == t)
{
cout<<"ans = "<<d+1<<endl;
return;
}
}
k = a[(cnt + mo[i]+9) % 9];
a[(cnt + mo[i]+9) % 9] = a[cnt];
a[cnt] = k;
}
q1.pop() ;
q2.pop() ;
}
}
int main()
{
bfs();
return 0;
}