第二题答案
第二题 跳蚱蜢
有9只盘子,排成1个圆圈。
其中8只盘子内装着8只蚱蜢,有一个是空盘。
我们把这些蚱蜢顺时针编号为 1~8
每只蚱蜢都可以跳到相邻的空盘中,
也可以再用点力,越过一个相邻的蚱蜢跳到空盘中。
请你计算一下,如果要使得蚱蜢们的队形改为按照逆时针排列,
并且保持空盘的位置不变(也就是1-8换位,2-7换位,…),至少要经过多少次跳跃?
注意:要求提交的是一个整数,请不要填写任何多余内容或说明文字。
#include<iostream>
#include<set>
#include<queue>
#include<malloc.h>
using namespace std;
struct zl{
char* state;
unsigned int level;
int pos;
zl(char* _state,unsigned int _level,int _pos):state(_state),level(_level),pos(_pos){}
};
struct cmp{
bool operator()(char* a,char* b){
return strcmp(a,b)<0;
}
};
queue<zl> q;
set<char*,cmp>all_state;
void swap(char* state,int pos,int new_pos){//改变状态
char t = state[pos];
state[pos] = state[new_pos];
state[new_pos] = t;
}
void add_node(char* state,int pos,int new_pos,unsigned int le){//节点入队+状态入集合
char* new_state = (char*)malloc(9*sizeof(char));
strcpy(new_state,state);
swap(new_state,pos,new_pos);
if(all_state.find(new_state) == all_state.end()){
all_state.insert(state);
q.push(zl(new_state,le+1,new_pos));
}
}
int main(){
char * a_state="012345678";
char* aim_state="087654321";
q.push(zl(a_state,0,0));//首个节点入队
all_state.insert(a_state);// 首个状态加入集合中
while(!q.empty()){ //队列实现广度优先所搜
zl front_node=q.front();
char * front_state=front_node.state;
unsigned int le = front_node.level;
int pos = front_node.pos;
if( strcmp(front_state,aim_state) ==0 ){//判断当前状态是否是目标状态
cout<<le<<endl;
return 0;
}
int pos1 = (pos-1+9)%9;
add_node(front_state,pos,pos1,le); //左一
int pos2 = (pos-2+9)%9;
add_node(front_state,pos,pos2,le); //左二
int pos3 = (pos+1+9)%9;
add_node(front_state,pos,pos3,le); //右一
int pos4 = (pos+2+9)%9;
add_node(front_state,pos,pos4,le); //右二
q.pop();
}
return 0;
}