poj1200 字符串hash

还不是很懂有一个bug,为什么一定要是nc进制

先贴一份ac慢速(94ms)代码

#include <iostream>
#include  <cstdio>
#include <algorithm>
#include <cstring>
#include <map>
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
int n, m;
const int maxn = 16000001;
char a[maxn];
bool mp[maxn];
int name[300];
int has;
ull p, h;
int main() {
    scanf("%d%d", &n, &m);
    scanf("%s", a + 1);
    h = 0, p = 1;
    has = m;
    int len = strlen(a + 1);
    int k = 0;
    for(int i = 1; i <= len; i++) {
        if(name[a[i]] == 0) name[a[i]] = ++k;
        if(k == m) break;
    }
    int cnt = 0;
    for(int i = 1; i + n - 1 <= len; i++) {
        ull sum = 0;
        for(int j = i; j <= i + n - 1; j++) {
//            sum = sum * has + a[j];
sum=sum*has+name[a[j]];
        }
        if(!mp[sum]) {
            mp[sum] = 1;
            cnt++;
        }
    }
    printf("%d\n", cnt);
    return 0;
}

再贴一份32ms的

#include <iostream>
#include  <cstdio>
#include <algorithm>
#include <cstring>
#include <map>
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
int n, m;
const int maxn = 16000001;
char a[maxn];
bool mp[maxn];
int name[300];
int has;
ull p, h;
int main() {
    scanf("%d%d", &n, &m);
    scanf("%s", a + 1);
    h = 0, p = 1;
    has = m;
    int len = strlen(a + 1);
    int k = 0;
    for(int i = 1; i <= len; i++) {
        if(name[a[i]] == 0) name[a[i]] = ++k;
        if(k == m) break;
    }
    int cnt = 0;
    ull sum = 0;
    for(int i = 1; i <= n; i++) {
        p *= has;
        sum = sum * has + name[a[i]];
    }
    cnt++;
    mp[sum] = 1;
    for(int i = 1 + n; i <= len; i++) {

//        for(int j = i; j <= i + n - 1; j++) {
////            sum = sum * has + a[j];
//            sum = sum * has + name[a[j]];
//        }
        sum = sum * has + name[a[i]] - p * name[a[i - n]];
        if(!mp[sum]) {
            mp[sum] = 1;
            cnt++;
        }
    }
    printf("%d\n", cnt);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/yiqzq/article/details/80049382