X星球的流行宠物是青蛙,一般有两种颜色:白色和黑色。
X星球的居民喜欢把它们放在一排茶杯里,这样可以观察它们跳来跳去。
如下图,有一排杯子,左边的一个是空着的,右边的杯子,每个里边有一只青蛙。
*WWWBBB
其中,W字母表示白色青蛙,B表示黑色青蛙,*表示空杯子。
X星的青蛙很有些癖好,它们只做3个动作之一:
1. 跳到相邻的空杯子里。
2. 隔着1只其它的青蛙(随便什么颜色)跳到空杯子里。
3. 隔着2只其它的青蛙(随便什么颜色)跳到空杯子里。
对于上图的局面,只要1步,就可跳成下图局面:
WWW*BBB
本题的任务就是已知初始局面,询问至少需要几步,才能跳成另一个目标局面。
输入为2行,2个串,表示初始局面和目标局面。
输出要求为一个整数,表示至少需要多少步的青蛙跳。
例如:
输入格式
WWBB
WWBB
则程序应该输出:
2
http://lx.lanqiao.cn/problem.page?gpid=T2835
这道题和8数码是同类型题。
八数码链接
都是求最短操作次数的,并且都是对字符串进行操作。
8数码ac代码:
#include <iostream> #include <queue> #include <unordered_map> #include <algorithm> using namespace std; unordered_map<string,bool> vis; int direction[4][2] = {{1,0},{-1,0},{0,1},{0,-1}}; string start; string e = "12345678x"; int bfs() { int step = 0; queue<string> q; q.push(start); vis[start] = true; while(!q.empty()) { int sz = q.size(); for(int i = 0; i < sz; i++) { string s = q.front(); q.pop(); int pos; if(s == e) return step; for(int i = 0; i < 9; i++) if(s[i]=='x') pos = i; int x = pos/3, y = pos % 3; for(int i = 0; i < 4; i++) { int newx = x + direction[i][0]; int newy = y + direction[i][1]; if(newx < 3 && newx >=0 && newy >= 0 && newy < 3) { string tmp = s; int newpos = newx*3 + newy; swap(tmp[newpos],tmp[pos]); if(vis[tmp] == false) { q.push(tmp); vis[tmp] = true; } } } } step++; } return -1; } int main() { char k; while(cin>>k) { if(k==' ') continue; else start+=k; } int res = bfs(); if(res == -1) cout<<"-1"; else cout<<res; }
注:进行字符串变化的时候,变化了就要还原回去,不然会影响下一次变化。有两种操作可以避免这种情况。第一种是手动还原,第二种是对临时变量进行变换。第二种更好。
青蛙跳杯子也是如此,跳的条件有三个,且都可以向左向右跳,因此有六个条件。每次跳就是交换两个字符的位置。记得要创建临时变量来进行变换,而不是对原字符串进行变换。
ac代码:
#include <iostream> #include <queue> #include <string> #include <map> using namespace std; string s, obj; queue<string> q; map<string, bool> vis; int bfs() { q.push(s); vis[s] = true; int step = 0; while(q.size()) { int sz = q.size(); for(int i = 0; i < sz; i++) { string t = q.front(); q.pop(); if(t == obj) return step; int u = t.find('*'); //cout << u << " "; for(int j = 0; j < 6; j++) { string tmp = t; //和相连的左边交换 if(j == 0 && u - 1 >= 0) swap(tmp[u], tmp[u - 1]); else if(j == 1 && u + 1 < t.size()) swap(tmp[u], tmp[u + 1]); else if(j == 2 && u - 2 >= 0) swap(tmp[u], tmp[u - 2]); else if(j == 3 && u + 2 < t.size()) swap(tmp[u], tmp[u + 2]); else if(j == 4 && u + 3 < t.size()) swap(tmp[u], tmp[u + 3]); else if(j == 5 && u - 3 >= 0) swap(tmp[u], tmp[u - 3]); if(vis[tmp] == true) continue; //cout << tmp << endl; q.push(tmp); vis[tmp] = true; } } step++; } return -1; } int main() { cin >> s; cin >> obj; cout << bfs(); }