poj1200

原题:

 

 题目意思大致是这样 

输入的NC 如4 说明输入的这个addbabac 有abcd四个不同字符

输入的N 如 3 是指子串长度

输入的s 如daababac是主串

我们要找主串中不同的连续子串数目 子串长度必须为N

如daababac 有

 

 这五个不同连续子串

 

这样一看 好像这个NC没啥用 我们先用最简单的方法写一遍

#include<cstdio>
#include<iostream>
#include<set>
#include<string>

using namespace std;
int main()
{
    int N,NC;
    scanf("%d%d",&N,&NC);
    string q;
    cin>>q;
    set<string> c;
    for(int i =0; i < q.size()-N+1;i++)
    {
        c.insert(q.substr(i,N));
    }
    cout<<c.size()<<endl;
    return 0;
}

我们直接暴力遍历一遍 把所有遍历的放了去重容器set中 再直接数set多少个元素就行

果不其然超时了。这种看似简单的题基本都会卡输入输出

所以想想怎么优化:

具体思路是

首先cin cout肯定不能有 

string也避免用 

就用c写不去用stl

然后再想想优化算法

我们之前是直接暴力比较

set是红黑树 插入的时间复杂度是O(logN)但是里边还有一个string的substr 这个substr截取子串的话如果用char数组,char*去想想实现原理

平均应该也有个n/2次 那时间复杂度是o(N)

 

 上边还有一个循环

这个时间复杂度粗略估算是三个乘起来 怎么也得比o(n²)o(n*m)高

所以算法必须优化。之前这个算法好处就是 set这个红黑树的logn时间复杂度还挺好 所以要善于用set

怎么优化呢 用哈希

这样这个NC就用上了

举个例子

对于addbabac 这个串 我们用c的语言特点

a虽然是char 但是int值也是97

a-z这些字符他们的int值本身也是哈希值 一一映射

这就方便我们直接用int数组记录哈希

还有就是 这个NC提示我们要用NC进制去标识 这个s转化的唯一NC进制数

之后我们把字符 字符串的比较转化为了数字的比较 

举个例子 10进制 每位就是0-9 唯一标识了一个数 假如abcd是 1234

就不会有adbb也是1234 和他重复 

ac代码:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define ll long long int
const int maxn = 16000000 + 3;
char s[maxn];
int not_0[maxn];
int num[301];
int N,NC;
void hash(char *s)
{
    int len = strlen(s);
    int temp = 0;
    num[s[0]] = temp++;  
    for(int i=1;i<len;i++)
    { 
        if(num[s[i]] == 0)
            num[s[i]] = temp ++;
    } //num[s[i]] char -> int
}
int get_cnt(int l,int r)
{
    int sum = 0;
    for(int i=l;i<=r;i++)
    {
        sum = sum * NC + num[s[i]];
    }
    return sum;
}
int main()
{
    while(~scanf("%d%d%s",&N,&NC,s))
    {
        int ans = 0;
        int len = strlen(s);
        hash(s);
        for(int i=0;i<=len-N;i++)
        {
            int cnt = get_cnt(i, i+N-1);
            if(!not_0[cnt])
            {
                ans ++;
                not_0[cnt] = 666;
            }
        }
        printf("%d\n",ans);
    }
    return 0;
}

 

posted @ 2022-01-18 15:17  然终酒肆  阅读(28)  评论(0编辑  收藏  举报