1. 程式人生 > >Crazy Search 【POJ

Crazy Search 【POJ

題目連結

題意:

給定一個字串,其中含有不同的字母數量為m,現在求這個字串中有多少個長度為n且長的互不相同的字元子串  舉個例子, n=3, m=4 ,字串 "daababac". 長度為3的不同的子串分別是: "daa"; "aab"; "aba"; "bab"; "bac". 因此, 答案是5. 

思路:

這裡沒有給N、M的範圍,但是要知道字串的數量最多是255(還不知是256),所以我們開了個300的陣列記錄對應字元的相應雜湊值,然後我們去遍歷這樣的字元,暴力就是了,每次查詢其1~N的字元是否對應的雜湊值出現過,沒有就記錄下來,這裡用不了set,會超時。。。

完整程式碼:

#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <limits>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#define lowbit(x) ( x&(-x) )
#define pi 3.141592653589793
#define e 2.718281828459045
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
const int maxN=1e6+5;
int N, M;
char s[maxN];
int tot, mp[300], sum;
bool vis[16000005];
void init()
{
    memset(vis, false, sizeof(vis));
    memset(mp, 0, sizeof(mp));
}
int main()
{
    while(scanf("%d%d", &N, &M)!=EOF)
    {
        init();
        getchar();
        scanf("%s", s);
        int len=(int)strlen(s);
        if(len<N) { printf("0\n"); continue; }
        for(int i=0; i<len; i++)
        {
            if(!mp[s[i]]) mp[s[i]]=++tot;
            if(tot==M) break;
        }
        int ans=0;
        for(int i=0; i+N<=len; i++)
        {
            sum=0;
            for(int j=0; j<N; j++)
            {
                sum=sum*M+mp[s[i+j]]-1;
            }
            if(!vis[sum])
            {
                vis[sum]=true;
                ans++;
            }
        }
        printf("%d\n", ans);
    }
    return 0;
}