计算重复

定义 conn(s,n) 为 n 个字符串 s 首尾相接形成的字符串,例如:

conn(“abc”,2)=”abcabc”
称字符串 a 能由字符串 b 生成,当且仅当从字符串 b 中删除某些字符后可以得到字符串 a。

例如“abdbec”可以生成“abc”,但是“acbbe”不能生成“abc”。

给定两个字符串 s1 和 s2,以及两个整数 n1 和 n2,求一个最大的整数 m,满足conn(conn(s2,n2),m) 能由 conn(s1,n1) 生成。

输入格式
输入包含多组测试数据。

每组数据由2行组成,第一行包含s2,n2,第二行包含s1,n1。

输出格式
对于每组数据输出一行表示答案m。

数据范围
s1 和 s2 长度不超过100,n1 和 n2 不大于 106。

输入样例:
ab 2
acb 4
acb 1
acb 1
aa 1
aaa 3
baab 1
baba 11
aaaaa 1
aaa 20
输出样例:
2
1
4
7
12
#include<bits/stdc++.h>

#define ll long long
using namespace std;
const int N = 105, M = 31;
ll f[N][M];
string s1, s2;
int n1, n2, sz1, sz2;

int main() {
    while (cin >> s2 >> n2 >> s1 >> n1) {
        sz1 = s1.size(), sz2 = s2.size();
        bool fail = false;
        for (int i = 0; i < sz1; i++) {
            int x = i, cnt = 0;
            f[i][0] = 0;
            for (int j = 0; j < sz2; j++) {
                while (s1[x] != s2[j]) {
                    x = (x + 1) % sz1;
                    if (++cnt >= sz1) {
                        fail = true;
                        puts("0");
                        break;
                    }
                }
                if (fail)break;
                f[i][0] += cnt + 1, cnt = 0;
                x = (x + 1) % sz1;
            }
            if (fail)break;
        }
        if (fail)continue;
        for (int j = 1; j < M; j++)
            for (int i = 0; i < sz1; i++)
                f[i][j] = f[i][j - 1] + f[(i + f[i][j - 1]) % sz1][j - 1];
        ll ans = 0, ns1 = n1 * sz1;
        for (int i = 0; i < sz1; i++) {
            ll x = i, res = 0;
            for (int j = M - 1; j >= 0; j--)
                if (x + f[x % sz1][j] <= ns1)
                    x += f[x % sz1][j], res += 1 << j;
            ans = max(ans, res);
        }
        ans /= n2;
        printf("%lld\n", ans);
    }
    return 0;
}
发布了329 篇原创文章 · 获赞 28 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_45323960/article/details/104890250