Total Submissions: 132 (35 users) Accepted: 36 (26 users)
[ My Solution ]
我们对字符串 S 做了以下定义:
1. S ^ k表示由k个字符串S构成的新字符串。 例如, S = "abc", k = 3, 则S ^ k = "abcabcabc"
2. Subsequence(S) 表示由字符串S的所有非空子序列构成的字符串集合。例如, S = "abc", 则Subsequence(S) = {"a", "b", "c", "ab", "ac", "bc", "abc"}
现在, 给你2个字符串S和T, 希望你能找到最小的k, 满足T ∈Subsequence(S ^ k)
输入只有2行, 分别为字符串S和T (1 <= |S|, |T| <= 100,000), 输入保证字符串S和T只由小写字母构成。
输出最小的k, 满足T ∈Subsequence(S ^ k), 若不存在这样的k, 则输出-1
abc
abacbc
3
题意:给字符串a[],b[],求需要几个a[]串,才能使b[]为a[]得字串。
解题思路:将a[]的每个字母在字符串的位置保存在结构体s中,例如
a[]={"abcdaa"}
那么s['a'].pos[]={1,5,6}
s['b'].pos[]={2}
..........
整形x为此时访问a[]的什么位置。
最后就是查询了,b[]中的一个字母在不在s中,或者在a的什么位置,用x记录下位置。
如果x比a[]长,说明已经访问完a[],添加一个a[]串 ,重新从a[]的头部开始查询。
#include<iostream>
#include<cstring>
using namespace std;
typedef struct infor{
int l;
int pos[100002];
}infor;
char a[100002],b[100002];
infor s[27];
int main()
{
while(cin>>a>>b){
int i,j,x=-1; //x标记现在访问到那个位置
int lena=strlen(a);
int lenb=strlen(b);
for(i=0;i<lena;i++)
s[a[i]-'a'].pos[s[a[i]-'a'].l++]=i;
int k=1,tag=0;
for(i=0;i<lenb;i++){
int flag=0;
if(!s[b[i]-'a'].l) //根本没存在这么字母
{
tag=1;
break;
}
if(x<lena)
{
for(j=0;j<s[b[i]-'a'].l;j++)
if(s[b[i]-'a'].pos[j]>x)
{
flag=1;
x=s[b[i]-'a'].pos[j];
break;
}
}
if(!flag)//存在这样一个字母,但字符串已经访问完了,添加一个字符串
{
k++;
i--;
x=-1;
}
}
if(tag)
cout<<"-1"<<endl;
else
cout<<k<<endl;
}
return 0;
}