牛客网:玛雅人的密码【bfs灵活应用】

在这里插入图片描述

做了这么多八数码,跳棋,五子棋,到头来bfs稍微变就卡住了ORZ,为自己的孱弱买单。其实就是一个裸着的bfs(我没试过dfs,不过dfs讲道理应该会快一点吧),始末状态已知,其实也可以用双向bfs,只不过最终状态比较多。简单理一下bfs的思路

卡就卡在搜索的状态这里,其实每个字符串就可以作为一个状态,每一次搜索到一个状态,我们遍历13种移位的方式,然后将没有出现过的状态加入集合即可。

#include<iostream>
#include<string>
#include<string.h>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<map>
#include<queue>
using namespace std;

#define ll int
#define MAX 105
#define inf 0x3fffffff

const string obj("2012");
ll len, res = 0;
map<string, ll> m;

//检查s串是否符合要求
bool check(string s) {
	for (int i = 0; i < len - 4; i++) {
		if (s.substr(i, 4) == obj)return true;
	}
	return false;
}

//从s节点进行扩展
ll bfs(string s) {
	queue<string>q; q.push(s); m[s] = 0;
	while (!q.empty()) {
		string t = q.front(), tmp = t; q.pop();
		if (check(t))return m[t];

		for (int i = 0; i < len - 1; i++) {
			swap(tmp[i], tmp[i + 1]);
			if (m.find(tmp) == m.end()) {//该字符状态没出现过 加入待访问队列
				q.push(tmp); m[tmp] = m[t] + 1;
			}
			swap(tmp[i], tmp[i + 1]);
		}
	}
	return -1;
}

int main() {
	ll n; string s;
	while (cin >> n >> s) {
		len = s.size(); m.clear(); res = 0;
		if (len < 4)cout << -1 << endl;
		if (len == 4 && s == "2012")cout << 0 << endl;
		cout << bfs(s) << endl;
	}
}
发布了269 篇原创文章 · 获赞 16 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/csyifanZhang/article/details/105614200