計算重複ios
這道題咱們先考慮樸素算法:算法
首先,咱們從\(s_1\)串的第一位開始,枚舉\(s_2\)每一位的對應位置,最後記錄最終能夠到達的位置,用每一位均如此,模擬便可。優化
該算法不夠好。spa
考慮優化:咱們設\(f[i,j]\)指\(s_1[i]\)打頭最少須要多少個字符串才能拼出\(2_{j}\)的\(s_2\)字符串來。code
\(f[i,0]\)暴力預處理。ci
最後在二進制拼湊時,沒必要枚舉每一位,由於第一位已經包含全部了。字符串
#include<iostream> #include<cstring> #include<string> #include<cstdio> #include<cmath> using namespace std; const int SIZE = 100 + 5; string s1, s2; int n1, n2; long long f[SIZE][32]; int main() { while(cin >> s2 >> n2 >> s1 >> n1) { memset(f, 0, sizeof(f)); bool fail = false; for(int i = 0; i < s1.size(); ++ i) { int k = i; for(int j = 0; j < s2.size(); ++ j) { int cnt = 0; while(s1[k % s1.size()] != s2[j]) { ++ k, ++ cnt; if(cnt >= s1.size()) { fail = true; break; } } k = (k + 1) % s1.size(); ++ cnt; f[i][0] += cnt; if(fail) break; } if(fail) break; } if(fail) { puts("0"); continue; } for(int j = 1; j <= 30; ++ j) { for(int i = 0; i < s1.size(); ++ i) { f[i][j] = f[i][j - 1] + f[(i + f[i][j - 1]) % s1.size()][j - 1]; } } long long m = 0, pos = 0; for(int i = 30; i >= 0; -- i) { if(pos + f[pos % s1.size()][i] <= s1.size() * n1) { pos += f[pos % s1.size()][i]; m += 1 << i; } } printf("%d\n", m / n2); } return 0; }