KMP
http://acm.hust.edu.cn:8080/judge/contest/view.action?cid=5866#problem/B
最小覆盖 len-next[len] 代码看到别人的 http://hi.baidu.com/ted11704/blog/item/013080ff913ba24a342acc70.html
http://acm.hust.edu.cn:8080/judge/contest/view.action?cid=5866#problem/E
算是dp吧!关键代码 ans[next[i]-1]+=ans[i-1]
#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;
const int maxn=100010;
char s[maxn];
int next[maxn];
void get_next(int len)
{
next[0]=-1;
int i=0,j=-1;
while(i<len)
{
if(j==-1||s[i]==s[j])
next[++i]=++j;
else j=next[j];
}
}
int ans[maxn];
void solve(int len)
{
for(int i=0;i<len;i++)
ans[i]=1;
for(int i=len;i>0;i--)
if(next[i]>0)
ans[next[i]-1]+=ans[i-1];
long long sum=0;
for(int i=0;i<len;i++)
sum+=(long long)ans[i];
printf("%lld\n",sum);
}
int main()
{
int ca;
scanf("%d",&ca);
while(ca--)
{
scanf("%s",s);
int len=strlen(s);
get_next(len);
solve(len);
}
return 0;
}
http://acm.hust.edu.cn:8080/judge/contest/view.action?cid=5866#problem/H
水题呀!因为才60,说以朴素匹配即可
#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;
char s[11][100];
int n;
bool check(int s1,int e)
{
for(int i1=1;i1<n;i1++)
{
int i=0,j=s1;
while(i<60&&j<e)
{
if(s[i1][i]==s[0][j]) i++,j++;
else i=i-(j-s1)+1,j=s1;
}
if(j<e) return 0;
}
return 1;
}
void solve()
{
string ans="";
for(int i=0;i<60;i++)
for(int j=i+2;j<60;j++)
{
if(check(i,j+1))
{
string cc=string(s[0]+i,s[0]+j+1);
if(ans=="") ans=cc;
else if(ans.length()<cc.length()) ans=cc;
else if(ans.length()==cc.length()&&ans>cc) ans=cc;
}
}
if(ans=="") puts("no significant commonalities");
else cout<<ans<<endl;
}
int main()
{
int ca;
scanf("%d",&ca);
while(ca--)
{
scanf("%d",&n);
for(int i=0;i<n;i++)
scanf("%s",s[i]);
solve();
}
return 0;
}
http://acm.hust.edu.cn:8080/judge/contest/view.action?cid=5866#problem/J
知道了最小覆盖 len-next[len] ,就是water了
#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;
const int maxn=1000010;
char s[maxn];
int next[maxn];
int get_next(int len)
{
next[0]=-1;
int i=0,j=-1;
while(i<len)
{
if(j==-1||s[i]==s[j]) next[++i]=++j;
else j=next[j];
}
return len-next[len];
}
int main()
{
while(scanf("%s",s)==1)
{
int len=strlen(s);
printf("%d\n",get_next(len));
}
return 0;
}
还是water http://acm.hust.edu.cn:8080/judge/contest/view.action?cid=5866#problem/K 算是kmp的一个应用吧
#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;
const int maxn=1000010;
char txt[maxn],s[10010];
int next[10010];
void get_next(int len)
{
next[0]=-1;
int i=0,j=-1;
while(i<len)
{
if(j==-1||s[i]==s[j]) next[++i]=++j;
else j=next[j];
}
}
void KMP()
{
int len1=strlen(txt),len2=strlen(s);
get_next(len2);
int i=0,j=0;
long long ans=0;
while(i<len1)
{
if(j==-1||txt[i]==s[j]) i++,j++;
else j=next[j];
if(j==len2) ans++,j=next[j];
}
printf("%lld\n",ans);
}
int main()
{
int ca;
scanf("%d",&ca);
while(ca--)
{
scanf("%s",s);
scanf("%s",txt);
KMP();
}
return 0;
}