玛雅人的密码—深度遍历

描述

玛雅人有一种密码,如果字符串中出现连续的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

解题思路:

(1)采用广度遍历的思想;

(2)定义字符结构体,含当前字符串,移动次数;

(3)遍历移动位置后的字符串是否含有2021;

代码:

#include <any>
#include <iostream>
#include <queue>
#include <string>
#include <cstdio>
using namespace std;

struct ss{ //定义字符串结构体
    int count;  //记录移动次数
    string s;  //记录当前字符串
};

queue<ss> q;  //定义队列容器
int result=-1;  //定义结果

int fact(int n){  //求阶乘
    if(n==0) return 1;
    else return n*fact(n-1);
}

bool check(string s){  //检查是否出现“2012”
    if(s.find("2012")!=string::npos) return true;
    else return false;
}

void bfs(ss str,int len){
    q.push(str);  //入队
    int flag=0;  //循环次数
    while (!q.empty()) {
        if (flag++>fact(len)) {  //不能超过len!次(最多移动次数)
            return;
        }
        ss st=q.front(); //取对头元素
        q.pop();  //出队
        if (check(st.s)==true) {  //判断是否在st出现2012
            result=st.count;
            return;
        }

        for(int i=0;i<len-1;i++){  //交换位置
            swap(st.s[i], st.s[i+1]);
            q.push({st.count+1,st.s}); 入队
            swap(st.s[i], st.s[i+1]); //回溯
        }
    }


}

int main(){

    int n;
    cin>>n;
    ss str;
    cin>>str.s;
    str.count=0; //初始化移动次数
    bfs(str,n);  //广度遍历
    cout<<result<<endl;


}

  • 9
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值