玛雅人的密码

本文介绍了一种通过字符串操作解密玛雅古老密码的算法。核心任务是在长度为N的字符串中,通过交换相邻字符来寻找2012序列,实现密码解锁。文章详细解析了使用队列和字符串匹配的解决方案,展示了如何通过递增交换次数来逼近目标序列。

题目描述
玛雅人有一种密码,如果字符串中出现连续的2012四个数字就能解开密码。给一个长度为N的字符串,(2=<N<=13)该字符串中只含有0,1,2三种数字,问这个字符串要移位几次才能解开密码,每次只能移动相邻的两个数字。例如02120经过一次移位,可以得到20120,01220,02210,02102,其中20120符合要求,因此输出为1.如果无论移位多少次都解不开密码,输出-1。

输入描述:
输入包含多组测试数据,每组测试数据由两行组成。
第一行为一个整数N,代表字符串的长度(2<=N<=13)。
第二行为一个仅由0、1、2组成的,长度为N的字符串。

输出描述:
对于每组测试数据,若可以解出密码,输出最少的移位次数;否则输出-1。

示例1
输入
5
02120
输出
1

题目个人理解:交换相邻的字符,02120交换一次是20120,01220,02210,02102,再将第一次交换后的结果再交换一次,20120交换后是02120,21020,20210,20102。所以需要记录每次交换后的结果,未找到时,在交换的基础上再进行交换,直至找到。
注:1,第二次交换02120已经测试过未出现,所以不需要再进行记录。
2,代码中使用队列queue进行保存交换后的字符串
3,代码中的pair是map中定义的方法,是将两种元素作为一种合成元素,添加方法有两种:pair<string,int>(“abc”,5)或make_pair(“abc”,5)

具体请看代码:

#include<iostream>
#include<string>
#include<queue>
#include<string.h>
#include<vector>
#include<algorithm>
using namespace std;
int changepassword(string str)
{
    queue<pair<string, int>> index;             //pair一个实用的小东西,可以将两个类型的元素绑在一起作为一个合成元素,不用定义结构体 
    index.push(make_pair(str, 0));             //make_pair访问元素的方法 ,或者pair<string,int>(str,0) 
    vector<string> visit;
    visit.push_back(str);
    while (!index.empty())
    {
        string temp = index.front().first;      //pair的访问,first是string类型数据 ,second是第二个int数据 
        int count = index.front().second;
        index.pop();                           //出队先进的字符串 
        for (int i = 0; i < temp.length() ; i++)
        { 
        	if(i == 0){                        //判断原始字符串是否有符合 
			    if (str.find("2012") != string::npos)
			        return count;
			}else{             
				string cur = temp;
	            swap(cur[i - 1], cur[i]);
	            if (cur.find("2012") != string::npos)            //string的匹配,!=string:npos代表有匹配的数据 
	                return count + 1;
	 
	            vector<string>::iterator it = find(visit.begin(), visit.end(), cur);  //vector查找数据cur并返回索引 
	            if (it== visit.end())                                // 是为了不将已经出现的再加入到数组中 
	            {
	                index.push(make_pair(cur, count + 1));
	                visit.push_back(cur);
	            }
			}
            
        }
    }
    return -1;
}
int main()
{
    int n;
    while (cin >> n)
    {
        string str;
        cin >> str;
        cout << changepassword(str) << endl;
    }
    return 0;
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值