题目描述
将S = [s,n]定义为由n个连接的字符串组成的字符串S. 例如,[“abc”,3] =“abcabcabc”。
另一方面,如果我们可以从s2中删除某些字符使其变为s1,我们定义字符串s1可以从字符串s2获得。 例如,“abc”可以根据我们的定义从“abdbec”获得,但不能从“acbbe”获得。
给你两个非空字符串s1和s2(每个最多100个字符)和两个整数0≤n1≤106和1≤n2≤106。现在考虑字符串S1和S2,其中S1 = [s1,n1] 和S2 = [s2,n2]。 找到最大整数M,使得可以从S1获得[S2,M]。
样例数据
input
s1=”acb”, n1=4
s2=”ab”, n2=2
output
2
数据规模与约定
时间限制:1s1s
空间限制:256MB
做法非常巧妙
我们先求出第一个串在第二个串最多可以出现的次数
这个怎么求呢?
我们可以对
拆分二进制
然后就可以记
表示从第二个串第
个位置开始匹配,匹配
个串一需要的位置
可以暴力求出
#include<bits/stdc++.h>
using namespace std;
#define rep(i,j,k) for(int i = j;i <= k;++i)
#define repp(i,j,k) for(int i = j;i >= k;--i)
#define rept(i,x) for(int i = linkk[x];i;i = e[i].n)
#define P pair<int,int>
#define Pil pair<int,ll>
#define Pli pair<ll,int>
#define Pll pair<ll,ll>
#define pb push_back
#define pc putchar
#define mp make_pair
#define fr first
#define se second
#define file(k) memset(k,0,sizeof(k))
#define ll long long
char s1[101] , s2[101];
int n1 , n2 , len1 , len2;
int dp[110][30];
void work()
{
len1 = strlen(s1);len2 = strlen(s2);memset(dp,0,sizeof(dp));
rep(st,0,len1-1)
{
int i = 0 , j = st , sum = 0;
int det = 0;
while(i < len2)
{
if(det > len1) {printf("0\n");return;}
if(s2[i] == s1[j]) i++,j++,sum++,det = 0;
else j++,sum++,det++;
j %= len1;
}
dp[st][0] = sum;
}
for(int j = 1;(1<<j) <= n1*len1/len2;++j)
rep(i,0,len1)
dp[i][j] = dp[i][j-1] + dp[ (dp[i][j-1] + i)%len1 ][j-1];
int x = len1*n1;
int now = 0;
int ans = 0;
repp(j,27,0)
if(dp[now][j] != 0 && x - dp[now][j] >= 0)
{
x -= dp[now][j];
now += dp[now][j];
now %= len1;
ans += 1<<j;
}
ans /= n2;
printf("%d\n",ans);
}
int main()
{
while(scanf("%s%d%s%d",s2,&n2,s1,&n1) == 4) work();
return 0;
}