Codeforces 91A Newspaper Headline
题目原址
[http://codeforces.com/problemset/problem/91/A]
题意
给两条字符串s1,s2。问你是否能用n条s1按顺序排成一条新的字符串,并从其中去掉任意个字符来得到s2,如果能,输出最小的n,否则输出-1
题解
预处理s1,用一个数组 a[i][j] 来表示在字符串s1下标大于等于i的部分中,下一个编号为j的字母的下标,无则用-1表示。
然后扫一遍s2,相同则下标增加,不同则跳转到相同为止,根据状况来增加答案。
(让循环完成后,s1[j]总要与s2[i]相同,这样不容易出错)
代码
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
typedef long long ll;
const int maxn = 1e6+7;
const int maxm = 1e4+7;
char s1[maxm],s2[maxn];
int a[maxm][26],b[26];
int main(){
ios::sync_with_stdio(false);
#ifdef LOCAL
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif // LOCAL
while(cin>>s1>>s2){
int len1=strlen(s1);
int len2=strlen(s2);
memset(b,0,sizeof(b));
memset(a,-1,sizeof(a));
b[s1[len1-1]-'a']++;
for(int i=len1-2;i>=0;i--){
b[s1[i]-'a']++;
for(int j=0;j<26;j++)
a[i][j]=(j==s1[i+1]-'a')?i+1:a[i+1][j];
a[i][s1[i]-'a']=i;
}
// for(int i=0;i<len1;i++){
// for(int j=0;j<26;j++)
// printf("%d ",a[i][j]);
// printf("\n");
// }
int flag=0;
for(int i=0;i<len2;i++)
if(!b[s2[i]-'a']){
flag=1;
break;
}
if(flag){
printf("-1\n");
continue;
}
int ans=1,j=0;
for(int i=0;i<len2;i++,j=(j+1)%len1){
if(s1[j]!=s2[i])
if(a[j][s2[i]-'a']!=-1)
j=a[j][s2[i]-'a'];
else{
ans++;
j=a[0][s2[i]-'a'];
}
// printf("i=%d j=%d,ans=%d\n",i,j,ans);
if(j==len1-1&&i!=len2-1)
ans++;
}
printf("%d\n",ans);
}
}