例题 POJ 1200 Crazy Search
解题思路: 将N个字符串分别转换成数字 然后按照 NC进制转换为 10进制
然后开一个标记数组进行标记(判定唯一性) 这样大大缩短了 时间
1600万-- 26个小写字母组合 再怎么 也不会太多
但是 不知道 到底是怎么推出的公式来的 进制转换为10进制(很神奇~~)
AC代码如下:
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<string.h>
#include<set>
using namespace std;
const int maxn=16000006;
char a[maxn];
bool hash[maxn];
int num[205];
int main()
{
int n,m;
while(~scanf("%d%d",&n,&m))
{
memset(num,0,sizeof(num));
memset(hash,0,sizeof(hash));
scanf("%s",a);
int len=strlen(a);
int cnt=0;
for(int i=0;i<len;i++)
if(!num[a[i]])
num[a[i]]=cnt++;
int ans=0;
for(int i=0;i<=len-n;i++)
{
int sum=0;
for(int j=i;j<=i+n-1;j++)
sum=sum*m+num[a[j]];
if(!hash[sum])
{
ans++;
hash[sum]=1;
}
}
cout<<ans<<endl;
}
return 0;
}
例题 POJ 1961 Period
解题思路: 就是kmp里的求next数组 然后依次扫一遍看是否出现循环节
AC代码如下:
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const int maxn=1000000+10;
int next[maxn];
string str;
int main()
{
int n;
int ans=0;
while(cin>>n&&n)
{
ans++;
cin>>str;
next[0]=next[1]=0;
for(int i=1;i<n;i++)
{
int j=next[i];
while(j&&str[i]!=str[j])
j=next[j];
next[i+1]=(str[i]==str[j])?j+1:0;
}
cout<<"Test case #"<<ans<<endl;
for(int i=2;i<=n;i++)
{
int len=i-next[i];
if(next[i]>0&&!(i%len))
cout<<i<<" "<<i/len<<endl;
}
cout<<endl;
}
return 0;
}