• 九度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
    来源:
    2012年清华大学计算机研究生机试真题

    思路:

      hash + BFS。

      BFS的题目经常搭配着hash,BFS题目最终要的一点是”剪枝“,假如不适当的剪枝可能会超时,这里用hash数组进行剪枝是一个好的方法。

           本题中hash采用三进制——因为字符串中只有0、1、2,对所有的字符串状态进行标记。

           和这个有些相似的题目有CCF 201604-4 游戏,也采用了状态标记的方法进行剪枝。

    #include <iostream>
    #include <stdio.h>
    #include <string>
    #include <math.h>
    #include <deque>
    #include <memory.h>
    using namespace std;
    
    string str;
    int N;
    
    bool visited[1600000];
    
    bool match(const string &str1) {
    
        for(int i = 0; i <= N-4; i ++) {
            if(str1.substr(i, 4) == "2012")
                return true;
        }
        return false;
    }
    
    int hash_func(string cur) {
        int res = 0;
        for(int i = 0; i < N; i ++)
            res = res*3+cur[i]-'0';
        return res;
    }
    
    int main() {
        while(scanf("%d", &N) != EOF) {
            cin >> str;
            memset(visited, 0, sizeof(visited));
    
            deque<string> record;
            record.push_back(str);
            int cur_lel = 1, nxt_lel = 0, ret = 0;
            bool found = false;
    
            while(!record.empty()) {
                string cur = record.front();
                record.pop_front();
                cur_lel --;
    
                if(match(cur)) {
                    found = true;
                    cout << ret << endl;
                    break;
                }
    
                for(int i = 0; i < N-1; i ++) {
                    swap(cur[i], cur[i+1]);
                    int hash_val = hash_func(cur);
                    if(!visited[hash_val]) {
                        visited[hash_val] = true;
                        record.push_back(cur);
                        nxt_lel ++;
                    }
                    swap(cur[i], cur[i+1]);
                }
    
                if(cur_lel == 0) {
                    cur_lel = nxt_lel;
                    nxt_lel = 0;
                    ret ++;
                }
    
            }
            if(!found)
                cout << -1 << endl;
        }
        return 0;
    }
  • 相关阅读:
    团对-爬取豆瓣电影top250-开发环境搭建过程
    团队编程项目作业2-团队编程项目代码设计规范
    团队编程项目作业3-模块测试过程
    团队编程项目作业3-模块开发过程
    课后作业-阅读任务-阅读提问-2
    简单团队-爬取豆瓣电影TOP250-代码设计规范
    简单团队-爬取豆瓣电影TOP250-设计文档
    简单团对-爬取豆瓣电影TOP250-开发环境搭建过程
    简单团队-爬取豆瓣电影TOP250-需求分析
    结对-英文词频检测程序-最终程序
  • 原文地址:https://www.cnblogs.com/starryxsky/p/7285882.html
Copyright © 2020-2023  润新知