码迷,mamicode.com
首页 > 其他好文 > 详细

5481: 问君能有几多愁

时间:2018-05-29 00:28:36      阅读:164      评论:0      收藏:0      [点我收藏+]

标签:计算   span   最大数   pre   例子   最大   %s   medium   mil   

描述

任何人都喜欢解决难题,其中一些可能会导致疯狂(比如害死人不偿命的(3n+1)猜想 )。

问君能有几多愁?恰似一江春水向东流。

一个难题就是找到给定字符串中不同子串的数目。聪明的人也是无法很快解决这个问题的,但是计算机可以的啊。你需要计算机的帮助和一个很好的算法来解决这样一个难题。

给定要寻找的子串的长度n,字符串出现的不同字符数nchar和字符串s,求出字符串s中出现的长度为n的不同子串的数目。

举一个例子,n=3,nchar=4和字符串“daababac”。在字符串s可以找到大小为3的不同子串是:"daa","aab","aba","bab","bac"。因此,答案应该是5。

输入

输入数据有多组。

每组第一行由两个数字n和nchar组成。

第二行为给定小写字母组成的字符串s。数据保证由可能的字符集所形成的子串的最大数目不超过1600000。

n不超过8,nchar不超过26,s的长度不超过1e6。

输出

每组输出一个整数,对应于给定字符串中找到的大小n的不同子串的数目。

样例输入

3 4
daababac
1 2
aba

样例输出

5
2

解题思路:哈希可能的字符串,has[i]=has[i-1]*p+idx(s[i]);

对于第一个样例(从1开始)

daa:

has[1]=4,has[2]=(4*27)+1,has[3]=(4*27+1)*27+1;

aab:

has[4]=1,has[5]=(1*27+1),has[6]=(1*27+1)*27+2;

所以has[6]=(has[3]%(27*27)*27+2);

#include <bits/stdc++.h>
using namespace std;
char a[1000002];
int main()
{
    int n,m,i,j,k;
    while(cin>>n>>m)
    {
        scanf("%s",a+1);
        set <long long> se;
        long long t=1,sum=0,len=strlen(a+1);
        for(i=1;i<n;i++) t=t*27;
        for(i=1;i<=len;++i)
        {
            if(i<=n)
            sum=sum*27+(a[i]-a+1);
            if(i==n) se.insert(sum);
            if(i>n)
            {
                sum=(sum%t)*27+(a[i]-a+1);
                se.insert(sum);
            }
        }
        cout<<se.size()<<endl;
    }
    return 0;
}

 

 

5481: 问君能有几多愁

标签:计算   span   最大数   pre   例子   最大   %s   medium   mil   

原文地址:https://www.cnblogs.com/ww123/p/9102679.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!