acwing 3385. 玛雅人的密码

Posted VanHope

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了acwing 3385. 玛雅人的密码相关的知识,希望对你有一定的参考价值。

题目传送门

题目描述

玛雅人有一种密码,如果字符串中出现连续的 2012 四个数字就能解开密码。

给定一个长度为 N 的字符串,该字符串中只含有 0,1,2 三种数字。

可以对该字符串进行移位操作,每次操作可选取相邻的两个数字交换彼此位置。

请问这个字符串要移位几次才能解开密码。

例如 02120 经过一次移位,可以得到 20120,01220,02210,02102,其中 20120 符合要求,因此输出为 11。

如果无论移位多少次都解不开密码,输出 −1。

输入格式

第一行包含一个整数 NN,表示字符串的长度。

第二行包含一个由 0,1,2 组成的,长度为 NN 的字符串。

输出格式

若可以解出密码,则输出最少的移位次数;否则输出 −1。

数据范围

2≤N≤13

输入样例:

5
02120

输出样例:

1

bfs

分析

这个题一样

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<unordered_map>
using namespace std;

bool is_have(string a, string b)

	for(int i = 0; i < a.size(); i++)
	
		int k = i;
		int j = 0;
		while( k < a.size() && j < b.size() && a[k] == b[j] )
		
			k++;
			j++;
		
		if(j == b.size()) return true;
	
	return false;


int bfs(string start)

	unordered_map<string, int> d; // 表示到某个状态的距离
	d[start] = 0;
	
	// bfs 常规操作 
	queue<string> q;
	q.push(start);
	
	while(q.size())
	
		string t = q.front();
		q.pop();
		int dis = d[t];
		
		if(t.find("2012") != -1) return d[t];
//		if(is_have(t, "2012")) return d[t];
		
		string next;
		for(int i = 0; i < t.size() - 1; i++)
		
			swap(t[i], t[i+1]);
			if(!d.count(t))
			
				d[t] = dis + 1;
				q.push(t);
			
			swap(t[i], t[i+1]);
			
	
	return -1; 

 
 
int main()

	int n;
	string start;
	cin >> n;
	cin >> start;
	
	cout << bfs(start) << endl;
	
	return 0;

时间复杂度

参考文章

以上是关于acwing 3385. 玛雅人的密码的主要内容,如果未能解决你的问题,请参考以下文章

清华机试-玛雅人的密码(广搜)

密码锁

算法提高 密码锁 (BFS)

P3385 模板负环

python 得到玛雅人的场景

P3385 模板负环