![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
问题描述 X星球的流行宠物是青蛙,一般有两种颜色:白色和黑色。 X星球的居民喜欢把它们放在一排茶杯里,这样可以观察它们跳来跳去。 如下图,有一排杯子,左边的一个是空着的,右边的杯子,每个里边有一只青蛙。 *WWWBBB 其中,W字母表示白色青蛙,B表示黑色青蛙,*表示空杯子。 X星的青蛙很有些癖好,它们只做3个动作之一: 1. 跳到相邻的空杯子里。 2. 隔着1只其它的青蛙(随便什么颜色)跳到空杯子里。 3. 隔着2只其它的青蛙(随便什么颜色)跳到空杯子里。 对于上图的局面,只要1步,就可跳成下图局面: WWW*BBB 本题的任务就是已知初始局面,询问至少需要几步,才能跳成另一个目标局面。 输入为2行,2个串,表示初始局面和目标局面。 输出要求为一个整数,表示至少需要多少步的青蛙跳。 样例输入 *WWBB WWBB* 样例输出 2 样例输入 WWW*BBB BBB*WWW 样例输出 10 数据规模和约定 我们约定,输入的串的长度不超过15 资源约定: 峰值内存消耗(含虚拟机) < 256M CPU消耗 < 1000ms 请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。 所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。 不要使用package语句。不要使用jdk1.7及以上版本的特性。 主类的名字必须是:Main,否则按无效代码处理。 ---------------------------- 笨笨有话说: 我梦见自己是一棵大树, 青蛙跳跃, 我就发出新的枝条, 春风拂动那第 5 层的新枝, 哦,我已是枝繁叶茂。
代码如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 struct node 5 { 6 string s; //排列类型 7 int step; //步数 8 node(string s,int step):s(s),step(step) 9 {} 10 }; 11 12 string s1,s2; 13 int ans; 14 map<string,int> mp; 15 16 void bfs() 17 { 18 int dir[6] = {-3,-2,-1,1,2,3,}; //青蛙可以移动的方向 19 queue<node> q; 20 q.push(node(s1,0)); 21 22 while (!q.empty()) 23 { 24 node t = q.front(); 25 q.pop(); 26 if (t.s == s2)//检索到目标排列,打印步数并退出 27 { 28 cout << t.step; 29 return ; 30 } 31 32 int k = t.s.size(); 33 for (int i=0 ; i<k ; i++) //遍历所有青蛙 34 { 35 for (int j=0 ; j<6 ; j++) //遍历可能移动的方向 36 { 37 int n = i+dir[j]; 38 string tmp = t.s; 39 if (n>=0 && n<=k && tmp[n]=='*')//合法范围内,且为空杯子可跳 40 { 41 swap(tmp[n],tmp[i]); //交换青蛙和空杯的位置 42 if (mp[tmp] == 0) //将本次的排列类型存储 43 { 44 mp[tmp] = 1; 45 q.push(node(tmp,t.step+1)); 46 } 47 } 48 } 49 } 50 } 51 return ; 52 } 53 54 int main(void) 55 { 56 cin >> s1 >> s2; 57 bfs(); 58 return 0; 59 }
解题思路:
本题数据量较少,使用广度优先遍历排序组合;
遍历所有青蛙可能的行动,每次遍历后进行查询是否为 新的排列组合 ,
如果是则进入队列,等待下次作为依据进行排序,否则舍弃
当遍历到符合的排列,输出步数并退出 (广度优先搜索到第一个即为最少步数)