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

题目描述

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

解题思路

这个题目的关键点就在于交换位置,所有的可能结果都是通过交换形成的,并且所求的也是交换所需要的最少次数。所以从交换次数着手,可以这么考虑问题:每次交换一次得到一个字符串,如果已经出现过则不用考虑,如果没有出现过,则判断是否有出现过“2012”。有的话交换次数则为原来字符串的交换次数加上1。

代码

#include <iostream>
#include <cmath>
#include <map>
#include <string>
#include <queue>
using namespace std;

string swap(string s,int i)
{
    string ans = s;
    char temp = s[i];
    ans[i] = ans[i + 1];
    ans[i + 1] = temp;
    return ans;
}

int main()
{
    int len;
    string str;
    string target = "2012";
    while(cin >> len >> str)
    {
        int ans = 0;
        map<string,int> mp;
        queue<string> q;
        mp[str] = 0;
        q.push(str);
        while(!q.empty())
        {
            string temp = q.front();
//            cout << temp << endl;
            q.pop();
            if(temp.find(target) != -1)
            {
                ans = mp[temp];
                break;
            }
            else
            {
                for(int i = 0;i < len - 1;i++)
                {
                    string now = swap(temp,i);
                    if(mp.find(now) == mp.end())
                    {
                        mp[now] = mp[temp] + 1;
                        q.push(now);
                    }
                }
            }
        }
        cout << ans << endl;
    }
    return 0;
}

  

原文地址:https://www.cnblogs.com/tracy520/p/8836499.html

时间: 2024-08-30 03:04:23

清华机试-玛雅人的密码(广搜)的相关文章

【九度OJ】题目1482:玛雅人的密码 (bfs+hash)

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

2012年清华:玛雅人的密码

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

九度OJ 1482:玛雅人的密码

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

清华机试-最小邮票数

题目描述 有若干张邮票,要求从中选取最少的邮票张数凑成一个给定的总值.     如,有1分,3分,3分,3分,4分五张邮票,要求凑成10分,则使用3张邮票:3分.3分.4分即可. 输入描述: 有多组数据,对于每组数据,首先是要求凑成的邮票总值M,M<100.然后是一个数N,N〈 20,表示有N张邮票.接下来是N个正整数,分别表示这N张邮票的面值,且以升序排列. 输出描述: 对于每组数据,能够凑成总值M的最少邮票张数.若无解,输出0. 示例1 输入 10 5 1 3 3 3 4 输出 3 解题思路

2014年七月华为校招机试题目--最难的一道, 呵呵!

今天百无聊赖之时, 漫心看到14年的华为校招机试题目, 一共三道, 前两道皆是平平, 第三道却柳暗花明, 让人眼前一亮. 咋一看, 饶有趣味, 看似平淡无奇, 然而却玄机颇深(对我这种弱渣而言).(不过对于ACMer, 好像应该用基础算法, 就能解决!) (然而我也只会基础的算法!!忏愧的紧!!!).如果有幸被大神看到, 能指点我一两招, 不胜感激!  下面是题目和我的详细题解思路(可供巨巨一笑!嘿嘿!). 2014年七月华为校招机试题目: 第三题: 输入一个正整数X,在下面的等式左边的数字之间

【转】朱兆祺教你如何攻破C语言学习、笔试与机试的难点(连载)

原文网址:http://bbs.elecfans.com/jishu_354666_1_1.html 再过1个月又是一年应届毕业生应聘的高峰期了,为了方便应届毕业生应聘,笔者将大学四年C语言知识及去年本人C语言笔试难点进行梳理,希望能对今年应届毕业生的应聘有所帮助. 2013年10月18日更新-->    攻破C语言这个帖子更新到这里,我不仅仅是为了补充大学学生遗漏的知识,我更重要的是希望通过我的经验,你们实际项目中的C语言写得漂亮,写出属于你的风格.“朱兆祺STM32手记”(http://bb

华为机试 宝典3 —擂台实战

首先推荐一个网站:acm.xidian.edu.cn/land/,上面的很多题目,难度很适合机试,如: 很简单:1031,1120,1122,1121,1103,1104,1281, 简单:1049,1181,1182,1279,1280, 中等:1106,1108,1183,1288. 难:1105,1282,1283, 大家可以根据自己的水平去训练,其实里面的难题也是很简单的,归类到题库中的话都属于简单题,只要好好看书学习都是可以做出来的,下面放几道例题,这些题都是机试很有可能考的题目,或者

华为机试—介绍、剖析、建议

一.华为机试介绍 1.大致介绍 时间:120分钟 环境:Visual Studio(去年是vs2005).Visual C++.VC 6.0.Eclipse(Java) 题量:共3题 初级题--60分--3组测试数据 中级题--100分--5组测试数据 高级题--160分--8组测试数据 注:初级题和中级题为必答题,高级题为附加题. 提交次数:每题最多5次 评判方式:按通过测试数据组数给分,每通过一组得20分 2.考试说明 这里有一个老版的机试考试说明,供大家参考: C/C++,JAVA机试流程

华为机试(6)

初级题描述:10个学生考完期末考试评卷完成后,A老师需要划出及格线,要求如下:  (1) 及格线是10的倍数:   (2) 保证至少有60%的学生及格:  (3) 如果所有的学生都高于60分,则及格线为60分  (4) 及格线越高越好,但最高不能超过60    输入:输入10个整数,取值0~100   输出:输出及格线,10的倍数   输入样例:61 51 49 30 20 10 70 80 90 99  输出样例:50 解题思路:从高到低枚举及格线,输出第一个满足要求的及格线就是答案 #inc