【POJ 1200】Crazy Search(将字符映射为数字,将NC进制hash成10进制)

题目链接

题目链接 http://poj.org/problem?id=1200

题意

原字符串有NC个不同字母,统计原字符串长度为N的子字符串个数

解题思路

  1. 将字符按ASCII码映射成数字。
  2. 将n个字符,即n位NC进制拼起来。
  3. 将拼起来的n位NC进制转化为10进制。
  4. 将10进制映射入hash表,每次映射判断是否已经存在。
    若不存在,则ans++;否则将hash设置为存在

如何将子串(n位NC进制)映射为10进制

a = 0

b = 1

c = 2

cbaa = 2 * 3^3 + 1 * 3^2 + 0 * 3^1 + 0 * 3^0

abcc = 0 * 3^3 + 1 * 3^2 + 2 * 3^1 + 2 * 3^0

时间复杂度

本题用的是map红黑树,查找插入时间为log(NC)

时间复杂度O(mlog(NC))

m为原字符串长度(题中并未给出),NC为进制数

代码如下(G++)

#include <iostream>
#include <string.h>
#include "map"
#include "string"

using namespace std;
typedef long long ll;
double eps = 1e-7;

// 将字符的ASCII码映射成整型
map <char, int> m;

// 将字符串子串按nc进制转化为10进制存入
bool hashs[16000010];

int main() {
    ios::sync_with_stdio(false);
    int nc,n;
    string s;
    while(cin >> n >> nc >> s){
        // 初始化
        memset(hashs,false, sizeof(hashs));
        m.clear();
        // 将字符映射为整型
        int cnt = 0;
        for(int i = 0;s[i]; ++i){
            if(m.find(s[i]) == m.end())
                m[s[i]] = cnt++;
        }

        int ans = 0;
        for(int i = 0;i <= s.length()-n;++i){
            // 将字符串s[i...i+n-1]的NC进制数转化为10进制
            int p = 0;
            for(int j =i;j < i+n;++j){
                p = p*nc+m[s[j]];
            }
            // 判断10进制是否存在,若存在则表示原字符串已经计数过一次
            if(!hashs[p]){
                ++ans;
                hashs[p] = true;
            }
        }
        cout << ans << endl;
    }
    return 0;
}

原文地址:https://www.cnblogs.com/zhangjiuding/p/11474022.html

时间: 2024-11-08 01:04:16

【POJ 1200】Crazy Search(将字符映射为数字,将NC进制hash成10进制)的相关文章

poj 1200 Crazy Search

题目: 链接:点击打开链接 题意: 输入n和nc,以及字符串s,输出长度为n的不同字串的个数. 算法: 思路: 用hash判重(hash值......),看了大牛的代码,对hash还是不甚理解.... 代码: #include<iostream> #include<cstring> #include<cstdio> #include<cstdio> using namespace std; #define MAXN 16000010 const int MA

POJ 1200 Crazy Search (字符串hash)

题目大意: 分析长度为n的子串有多少种. 思路分析: 对于没出现的字符,将其分配一个数字. 然后将子串看做一个nc进制的数. 然后hash判断. #include <cstdio> #include <iostream> #include <algorithm> #include <map> #include <cstring> #include <string> using namespace std; bool vis[26666

POJ 1200 Crazy Search(Hash)

Description Many people like to solve hard puzzles some of which may lead them to madness. One such puzzle could be finding a hidden prime number in a given text. Such number could be the number of different substrings of a given size that exist in t

Poj 1200 Crazy Search(字符串Hash)

Poj 1200 题意:给你一个n和m以及一个有m个不同字母组成的字符串,问有多少个长度为n的不同字符子串: 题解:以m为进制进行Hash.虽然是看了解题报告才会的但必须要理解并且学会运用:https://www.cnblogs.com/gj-Acit/archive/2013/05/15/3080734.html. #include<cstring>//别用set,set的添加是红黑树实现时间复杂度是O(logN),在这里会超时 #include<cstdio> #define

Crazy Search

poj1200:http://poj.org/problem?id=1200 题意:给你一个有m种字符串,求长度为n的连续子串由多少种. 题解:网上的代码都是hash,但是本人觉得hash有问题,就是n,m稍微大点,hash的值都会爆出int,无法开数组来记录该串是否被记录.可能数据弱,结果hash竟然A了 .正确的解法是用set来存,把所有的hash值放进set,set有去重效果,最后求一下set的大小.但是这样结果是T了.不知道这题怎么解.一下是第一种代码.于是换别的,trie树来搞. Cr

poj 1200 --- 不错的字符串HASH构造方法

题目:http://poj.org/problem?id=1200 题意:给一个字符串,给定n和nc,字符串里最多有nc个不同的字符,问长度为n的不同子串最多有几个 和上一篇现场赛那个一样,也是难在判重处理不好会超时 方法:将长度为n的子串映射为一个nc进制的数,开一个大数组,判断是否重复 #include <cstdio> #include <cstring> #include <algorithm> #include <string> #include

[poj1200]Crazy Search(hash)

Crazy Search Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 26713 Accepted: 7449 Description Many people like to solve hard puzzles some of which may lead them to madness. One such puzzle could be finding a hidden prime number in a given

POJ 1200 字符串HASH

题目链接:http://poj.org/problem?id=1200 题意:给定一个字符串,字符串只有NC个不同的字符,问这个字符串所有长度为N的子串有多少个不相同. 思路:字符串HASH,因为只有NC个不同的字符,所以我们可以把字符串看成是一个NC进制的串,然后计算出字符串的前缀HASH.然后枚举起点判断子串的HASH值是否已经存在.因为有了前缀HASH值,所以转移是O(1)的. #define _CRT_SECURE_NO_DEPRECATE #include<iostream> #in

poj 1200 (hash)

Crazy Search Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 23168   Accepted: 6513 Description Many people like to solve hard puzzles some of which may lead them to madness. One such puzzle could be finding a hidden prime number in a gi