zoukankan      html  css  js  c++  java
  • 九度oj 题目1482:玛雅人的密码 清华大学机试

    题目描述:

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

    样例输入:
    5
    02120
    样例输出:
    1

    这个题第一眼看上去好像不难,但做起来却不知道如何下手。一开始思路往动态规划上靠,可是状态转移方程真实难以想明白。
    想了很久,实在是想不明白,只好翻了翻别人的题解,这才知道原来是用广度优先搜索来做。
    一道题找对方法真的很重要。

    那么搜索时状态即为字符串的排列情况,利用map来记录该状态是否被访问过。检查每一个状态是否符合要求,一旦符合,就是最小的次数。

    代码如下
     1 #include <cstdio>
     2 #include <cstring>
     3 #include <iostream>
     4 #include <string>
     5 #include <map>
     6 #include <queue>
     7 
     8 using namespace std;
     9 int cnt[3];
    10 typedef pair<string, int> Node;
    11 map <string, int> mapping;
    12 
    13 string str;
    14 queue <Node> que;
    15 
    16 bool isOk(string s) {
    17     int len = s.size();
    18     for (int i = 0; i <= len-4; i++) {
    19         if (s[i] == '2' && s[i + 1] == '0' && s[i + 2] == '1' && s[i + 3] == '2') {
    20             return true;
    21         }
    22     }
    23     return false;
    24 }
    25 
    26 int main() {
    27     int n;
    28     while (scanf("%d", &n) != EOF) {
    29         cin >> str;
    30         int len = str.size();
    31         memset(cnt, 0, sizeof(cnt));
    32         for (int i = 0; i < len; i++) {
    33             cnt[str[i] - '0']++;
    34         }
    35         if (cnt[0] < 1 || cnt[1] < 1 || cnt[2] < 2) {
    36             puts("-1");
    37             continue;
    38         }
    39         while (!que.empty()) {
    40             que.pop();
    41         }
    42         mapping.clear();
    43         mapping[str] = 1;
    44         que.push(Node(str, 0));
    45         int ans = -1;
    46         while (!que.empty()) {
    47             Node p = que.front(); que.pop();
    48             string t = p.first;
    49             int step = p.second;
    50             if (isOk(t)) {
    51                 ans = step;
    52                 break;
    53             }
    54             for (int i = 0; i+1 < len; i++) {
    55                 string tmp = t;
    56                 swap(tmp[i], tmp[i + 1]);
    57                 if (mapping.find(tmp) == mapping.end()) {
    58                     mapping[tmp] = 1;
    59                     que.push(Node(tmp, step + 1));
    60                 }
    61             }
    62 
    63         }
    64         printf("%d
    ", ans);
    65         
    66     }
    67     return 0;
    68 }

    这种题题面很简单,做起来代码其实也很简单,但就是想不到该用什么样的方法,但一旦找对方法,问题就迎刃而解了

  • 相关阅读:
    数据结构与算法——红黑树
    JAVA数据结构——Map之HashMap
    JAVA数据结构——集合之LinkedList
    在Mac OS X下让你的Terminal带上Color
    Git使用指南(一)
    《乔布斯传》摘录
    必应语音API(Bing text to speech API)
    《设计心理学2》 摘录
    《设计心理学1》 摘录
    第10组 Beta冲刺(4/4)
  • 原文地址:https://www.cnblogs.com/jasonJie/p/5881959.html
Copyright © 2011-2022 走看看