【蓝桥杯】跳蚱蜢
题目连接http://oj.ecustacm.cn/problem.php?id=1318
1.1建模
直接让蚱蜢跳到空盘有点麻烦,因为有很多蚱蜢在跳,跳晕了。如果看成空盘跳到蚱蜢的位置就简单多了,只有一个空盘在跳。
题目给的是一个圆圈,不好处理,此时祭出一个建模大法:“化圆为线”! 把空盘看成0,那么有9个数字{0,1,2,3,4,5,6,7,8},一个圆圈上的9个数字,拉直成了一条线上的9个数字。
等等,这不就是八数码问题吗?八数码是经典的BFS问题。
八数码有9个数字{0,1,2,3,4,5,6,7,8},它有9!=362880种排列。也不多,
本题的初始状态是“012345678”,终止状态是“087654321”。
从初始状态跳一次,有4种情况:
1.2代码的思路
这道题要采用的是BFS来遍历,每一个结点有四个根节点,层次遍历过去,队列的一个点是用结构体表示,存放的是字符串和当前的总步骤,当出现087654321的时候就结束,另外,要用一个map来判重,map<string,bool>mp;如果是false(没出现过该串),则标记为false并且加入队列中去,整体主要思路差不多这样。
1.3完整代码
#include<bits/stdc++.h>
using namespace std;
struct node{
string s;
int t;
node(){}
node(string ss,int tt)
{
s=ss;t=tt;
}
};
map<string,bool>mp;
queue <node> q;
void BFS_solve(){
while(!q.empty())
{
node now=q.front();
q.pop();
string s=now.s;int t=now.t;
if(s=="087654321")
{
cout<<t;
break;
}
int i;
for(i=0;i<10;i++)
{
if(s[i]=='0')
break;
}//找到字符0
for(int j=i-2;j<=i+2;j++)
{
int k=(j+9)%9;
if(k==i) continue;
char tmp;
tmp = s[i];s[i] = s[k];s[k] = tmp;//相当于0的位置在跳
if(!mp[s])//当前排列顺序的串没有被遍历过
{ mp[s]=true;
q.push(node(s,t+1));
}
tmp=s[k];s[k]=s[i];s[i]=tmp;//广度遍历的一个点已经加入队列了,要把串变回来才能继续遍历同层次的点
}
}
}
int main()
{
string s="012345678";
node n0=node(s,0);
q.push(n0);
mp[s]=true;
BFS_solve();
}