CF 314B: Sereja and Periods

博客介绍了Codeforces竞赛中的一道题目314B - Sereja and Periods,讨论如何找到最大的整数p,使得[q, p]是字符串w的子序列。文章提到了两种解法,一种是预处理匹配策略,另一种利用了倍增思想,并提供了相关参考代码链接。" 132704311,19673616,使用OpenCV在图像上添加边框的Python教程,"['计算机视觉', '图像处理', 'OpenCV', 'Python']
摘要由CSDN通过智能技术生成

题目链接:http://codeforces.com/contest/314/problem/B


题意:

对于字符串s和正整数n,规定[s,n]=s+s+……+s;

  ["abc", 2] ="abcabc"

现给出w = [a, b] , q = [c, d]

求最大的p,使得 [q, p]是w的子序列

如无合法p,则输出0



由于CF可以看代码的缘故,一般不写CF题解。

但是觉得这道题确实比较巧妙,于是记录一下。


做这道题时参考了两位神犇的代码:

http://codeforces.com/contest/314/submission/3832474

http://codeforces.com/contest/314/submission/3845338

谢谢!


算法:


解法一:

预处理若从c串的第i位开始匹配,

那么在a串中最多可以循环匹配c串的多少位。


解法二:

借用倍增的思想。

go[dep][get_id(i,j)]表示从字符串a的第i位,字符串c的第j位开始,匹配字符串c的(2^dep)位后

.first表示两个字符串匹配后到达的位置

.second表示“消耗”了多少个a串

注意,很显然在存在合法解的情况下

消耗a串的数量和c串的数量都不会超过int,

但是在不存在合法解的情况下,

.second初始化为INF,经过多次倍增可能会超过int


代码如下:


解法一:

#include<cstdio>
#include<iostream>
#include<sstream>
#include<cstdlib>
#include<cstring>
#include<string>
#include<climits>
#include<cmath>
#include<algorithm>
#include<queue>
#include<vector>
#include<stack>
#include<set>
#include<map>
#define INF 0x3f3f3f3f
#define eps 1e-8
using namespace std;

const int MAXN=110;
char a[MAXN],c[MAXN];
int nxt[2][MAXN];

int main() {
    int b,d;
    scanf("%d%d",&b,&d);
    scanf("%s%s",a,c);
    int len1=strlen(a);
    int len2=strlen(c);
    for(int j=0; j<len2; j++) {
        int cur=j;
        nxt[0][j]=0;
        for(int i=0; i<len1; i++) {
            if(c[cur]==a[i]) {
                cur++;
                if(cur==len2) {
                    nxt[0][j]++;
                    cur=0;
                }
            }
        }
        nxt[1][j]=cur;
    }
    long long ans=0LL;
    int cur=0;
    for(int i=0; i<b; i++) {
        ans+=nxt[0][cur];
        cur=nxt[1][cur];
    }
    printf("%I64d\n",ans/d);
    return 0;
}


解法二:

#include<cstdio>
#include<iostream>
#include<sstream>
#include<cstdlib>
#include<cstring>
#include<string>
#include<climits>
#include<cmath>
#include<algorithm>
#include<queue>
#include<vector>
#include<stack>
#include<set>
#include<map>
#define INF 0x3f3f3f3f
#define eps 1e-8
using namespace std;

const int MAXN=110;
const int MAXM=30;
char a[MAXN],c[MAXN];
int len1,len2;
pair<int,long long> go[MAXM][MAXN*MAXN];

int get_id(int i, int j) {
    return i*len2+j;
}

long long solve(int dis) {
    int cur=get_id(0,0);
    long long cot=0;
    for (int i=0; i<MAXM; i++) {
        if(dis>>i&1) {
            cot+=go[i][cur].second;
            cur=go[i][cur].first;
        }
    }
    return cot;
}

int main() {
    int b,d;
    scanf("%d%d",&b,&d);
    scanf("%s%s",a,c);
    len1=strlen(a);
    len2=strlen(c);
    for(int i=0; i<len1; i++) {
        for(int j=0; j<len2; j++) {
            int id=get_id(i,j);
            go[0][id]=make_pair(id,INF);
            for(int k=0; k<len1; k++) {
                if(a[(i+k)%len1]==c[j]) {
                    go[0][id]=make_pair((get_id((i+k+1)%len1,(j+1)%len2)),(i==0)||((i+k)/len1));
                    break;
                }
            }
        }
    }
    for(int i=1; i<MAXM; i++) {
        for(int j=0; j<len1*len2; j++) {
            int nxt=go[i-1][j].first;
            go[i][j]=make_pair(go[i-1][nxt].first, go[i-1][j].second+go[i-1][nxt].second);
        }
    }
    int l=0;
    int r=INF;
    while(l<r) {
        int mid=(l+r+1)>>1;
        if(solve(mid)<=b) {
            l=mid;
        } else {
            r=mid-1;
        }
    }
    printf("%d\n",l/(len2*d));
    return 0;
}

报错信息提示缺少`seasonal_periods`参数,并且索引没有已知的频率。这是因为在使用`get_forecast()`方法时,需要提供`seasonal_periods`参数来指定季节性的周期。如果你的数据具有季节性,你可以通过指定正确的`seasonal_periods`值来解决此问题。 在ARIMA模型中,可以使用`seasonal_order`参数来指定季节性的阶数。例如,如果数据具有每年一次的季节性,你可以将`seasonal_order=(0, 0, 0, 12)`设置为每12个月一次的季节性。 以下是修改后的代码示例: ```python import pandas as pd from statsmodels.tsa.arima.model import ARIMA # 构造补贴数据 data = [289.25, 0.6, 345.53, 20.68, 387.95, 286.91, 1.36, 0.34, 11.4, 72.9, 303.46, 420.6, 282.59, 104.15, 52.2] index = pd.date_range(start='2022-01-01', periods=len(data), freq='MS') df = pd.DataFrame(data, index=index, columns=['subsidy']) # 拟合ARIMA模型 model = ARIMA(df['subsidy'], order=(1, 0, 0), seasonal_order=(0, 0, 0, 12)) model_fit = model.fit() # 预测2023年7月-2023年12月的补贴数据 forecast_start = pd.to_datetime('2023-07-01') forecast_end = pd.to_datetime('2023-12-01') forecast = model_fit.get_forecast(steps=6, seasonal=True) forecast_values = forecast.predicted_mean # 打印预测结果 forecast_index = pd.date_range(start=forecast_start, end=forecast_end, freq='MS') forecast_df = pd.DataFrame(forecast_values, index=forecast_index, columns=['forecast']) print(forecast_df) ``` 请注意,代码中通过`pd.date_range()`函数生成了一个每月的时间索引,然后将其作为DataFrame的索引。在拟合ARIMA模型时,我们使用了`seasonal_order=(0, 0, 0, 12)`来指定每年一次的季节性。你可以根据实际数据的季节性进行调整。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值