5481: 問君能有幾多愁
阿新 • • 發佈:2018-05-29
rom CI 最大數 就是 ace 小寫 pre mes 最大
描述
任何人都喜歡解決難題,其中一些可能會導致瘋狂(比如害死人不償命的(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: 問君能有幾多愁