标题:跳蚱蜢
如图 p1.png 所示:
有9只盘子,排成1个圆圈。
其中8只盘子内装着8只蚱蜢,有一个是空盘。
我们把这些蚱蜢顺时针编号为 1~8
每只蚱蜢都可以跳到相邻的空盘中,
也可以再用点力,越过一个相邻的蚱蜢跳到空盘中。
请你计算一下,如果要使得蚱蜢们的队形改为按照逆时针排列,
并且保持空盘的位置不变(也就是1-8换位,2-7换位,…),至少要经过多少次跳跃?
注意:要求提交的是一个整数,请不要填写任何多余内容或说明文字。
答案是20步
#include<bits/stdc++.h>
#include<iostream>
#include<queue>
#include<set>
#include<cstring>
using namespace std;
string start_state = "012345678";
string end_state = "087654321";
struct state{
string number;
int step;
int pos0;
state(string number1,int step1,int pos01):number(number1),step(step1),pos0(pos01){
}
};
int main(){
set<string> allstate;
queue<state> q;
state ini(start_state,0,0);
int next[4]={-1,-2,1,2};
q.push(ini); //将初始状态加入队列
allstate.insert(start_state);// 将初始数字加入set
while(!q.empty()){
state now = q.front(); //将队首的元素的内容读出
string ss = now.number;
int pos0_now = now.pos0;
int step_now = now.step;
if(ss==end_state){ //判断是否到达目标状态
cout<<step_now;
return 0;
}
for(int i=0;i<4;i++){ //循环四种可能
ss = now.number; //!!!这里一定要在每回循环开始的时候赋初值,不然ss每次经过swap()都会改变状态
int new_pos = (pos0_now+9+next[i])%9; //这里要+9 因为如果不加9 -1 -2的时候回越出数组边界
swap(ss[new_pos],ss[pos0_now]); //移动0的位置
if(allstate.find(ss)!=allstate.end()) continue; //判断该数字是否已经存在于set中
allstate.insert(ss); //将这个数字加入set中
// cout<<new_pos<<" "<<pos0_now<<" ";
// cout<<ss<<endl;
state newstate(ss,step_now+1,new_pos);
q.push(newstate); //将这个结点入队
}
q.pop();
}
return 0;
}