搜索_BFS_双向BFS_CH2908_字串变换

版权声明:本文为博主原创作品, 转载请注明出处! https://blog.csdn.net/solider98/article/details/84338035

点此打开题目页面

思路分析:

    为减小搜索树规模, 考虑同时从起始串A正向广搜和从目标串B逆向广搜, 两个搜索树每次各搜索一层, 具体实现上的细节以及需要注意的问题参见下面的AC代码:

//CH2908_字串变换
#include <iostream>
#include <cstdio>
#include <map>
#include <string>
#include <queue>
#include <algorithm>
#define mp make_pair
#define fi first
#define se second
using namespace std;
typedef pair<string, int> psi; typedef pair<string, string> pss;
const int MAX = 30, INF = 0x3f3f3f3f; const string END = "";
string A, B; pss rule[MAX]; int rcnt;//变换规则, 规则个数 
queue<string> qa, qb; map<string, int> ma, mb;//qa: 从A开始的广搜队列, qb: 从B开始广搜队列 
int main(){
	cin >> A >> B; while(cin >> rule[++rcnt].fi) cin >> rule[rcnt].se; --rcnt;
	qa.push(A), qa.push(END), ma[A] = 0, qb.push(B), qb.push(END), mb[B] = 0;
	int res = INF, nowa = 0; //nowa: qa当前以完成的变换次数 
	while(nowa <= 6 && (qa.size() >= 2 || qb.size() >= 2)){
		while(!qa.empty()){
			string s = qa.front(); qa.pop();
			if(s == END){
				qa.push(END); break;
			}
			if(mb.count(s)){
				res = 2 * nowa - 1; goto GOTO1;
			}
			int scnt = ma[s];
			for(int i = 1; i <= rcnt; ++i){
				string l = rule[i].fi, r = rule[i].se; int beg = 0;
				while(beg < s.length()){
					string ts = s; string::size_type pos = ts.find(l, beg);
					if(pos == string::npos) break;
					ts.replace(pos, l.length(), r), beg = pos + 1;
					if(ma.count(ts)) continue;
				    ma[ts] = scnt + 1, qa.push(ts);			
				}
			}
		}
		++nowa; 
		while(!qb.empty()){
			string s = qb.front(); qb.pop();
			if(s == END){
				qb.push(END); break;
			}
			if(ma.count(s)){
				res = 2 * (nowa - 1); goto GOTO1;
			}
			int scnt = mb[s];
			for(int i = 1; i <= rcnt; ++i){
				string l = rule[i].se, r = rule[i].fi; int beg = 0;
				while(beg < s.length()){
					string ts = s; string::size_type pos = ts.find(l, beg);
					if(pos == string::npos) break;
					ts.replace(pos, l.length(), r), beg = pos + 1;
					if(mb.count(ts)) continue;
					mb[ts] = scnt + 1, qb.push(ts);
				}
			}
		}
	}
	GOTO1: if(res == INF) cout << "NO ANSWER!" << endl; else cout << res + 1 << endl;
}

猜你喜欢

转载自blog.csdn.net/solider98/article/details/84338035