Educational Codeforces Round 144 (Rated for Div. 2)(A,B,C,D)
Educational Codeforces Round 144 (Rated for Div. 2)(A,B,C,D)
本来这场我是要
A
这个就是求一个串是不是另外一个串的子串,我都知道了这个另外一个串是什么了,就是我是自己写的判断两个字符串是否是为子串的关系写错了(还是太弱了),其实我们可以看到
我觉得我在做这个题的时候没有看到那个
#include <iostream>
#include <string>
using namespace std;
const int manx=2e5+10;
int t,n;
string ss="FBFFBFFB";
void solve()
{
string s;
cin>>n;
cin>>s;
if (ss.find(s)!=-1)
{
cout<<"YES\n";
}
else cout<<"NO\n";
return ;
}
int main ()
{
cin>>t;
ss=ss+ss+ss;
while (t--)
{
solve();
}
system ("pause");
return 0;
}
B
这个是我后面自己写的
题目大意就是我们可以用一个既有
我们可以知道,如果对于两个字符串都存在的字符,那么那么这一个字符就可以直接显示出来,而不需要通过
然后我们对于那些不同的,我们直接用
然后我们还知道
所以我们只有两端的字符是一样的,那么我们后面都由
那么对于那些两端不同的,只有中间存在两个连续的字符在两个字符串里面是一样的,那么就会变成
#include <iostream>
#include <string>
using namespace std;
const int maxn=2e5+10;
#define yes cout<<"YES\n"
#define no cout<<"NO\n";
int t;
string s,ss;
void solve()
{
cin>>s>>ss;
if (s[0]==ss[0])
{
yes;
cout<<s[0]<<"*\n";
return ;
}
int n=s.size(),nn=ss.size();
if (s[n-1]==ss[nn-1])
{
yes;
cout<<"*"<<s[n-1]<<'\n';
return ;
}
for (int i=0;i+1<n;i++)
{
for (int j=0;j+1<nn;j++)
{
if (s[i]==ss[j]&&s[i+1]==ss[j+1])
{
yes;
cout<<"*"<<s[i]<<s[i+1]<<"*\n";
return ;
}
}
}
no;
return ;
}
int main ()
{
cin>>t;
while (t--)
{
solve();
}
system ("pause");
return 0;
}
C
题目大意就是给你一对
首先我们需要知道这个最大的数量是多大
要满足数量最多,那么这个最小的数一定是
对于最大的数是最小的数的
但是注意对于把任意个
#include <iostream>
#include <cmath>
using namespace std;
#define int long long
const int mod=998244353;
int n,t,l,r;
int c[40][40];
void init()
{
for (int i=0;i<=30;i++)
{
for (int j=0;j<=i;j++)
{
if (!j)
{
c[i][j]=1;
}
else
{
c[i][j]=c[i-1][j-1]+c[i-1][j];
}
}
}
return ;
}
void solve()
{
cin>>l>>r;
int len=__lg(r/l);
int mul=1<<len;
int ans=0;
for (int i=0;i<=len;i++)
{
if (l*mul>r) break;
ans=(ans+c[len][i]*(r/mul-l+1)%mod)%mod;
mul=mul*3/2;
}
cout<<len+1<<" "<<ans<<'\n';
return ;
}
signed main ()
{
cin>>t;
init();
while (t--)
{
solve();
}
system ("pause");
return 0;
}
D
这个大意是给你一个
这个我们可以参考普通的最大字段和
for (int i=1;i<=n;i++)
{
dp[i]=max(dp[i-1]+a[i],a[i]);//以i为结尾的最大子段和
}
然后我们这个题还需要选择
所以我们还需要多一维来表达这个位置是加还是减,还需要记录此时已经有了多少个加了
那么对于
然后我们就可以很容易的得出状态转移方程
if (i>j)//最多只能有i-1个,他前面只有i-1个位置(不包括i),第i个进行减法操作
{
dp[i][j][0][0]=max(dp[i-1][j][0][0],max(dp[i-1][j][0][1],max(dp[i-1][j][1][0],max(dp[i-1][j][1][1],0ll))));
dp[i][j][0][1]=max(dp[i-1][j][0][1]+t0,max(dp[i-1][j][1][1]+t0,t0));
}
if (j)//加法操作,这一项的j可以等于i,可以前面到i都是加法
{
dp[i][j][1][0]=max(dp[i-1][j-1][0][0],max(dp[i-1][j-1][0][1],max(dp[i-1][j-1][1][0],max(dp[i-1][j-1][1][1],0ll))));
dp[i][j][1][1]=max(dp[i-1][j-1][0][1]+t1,max(dp[i-1][j-1][1][1]+t1,t1));
}
具体代码如下
#include <iostream>
using namespace std;
const int maxn=2e5+10;
#define int long long
int dp[maxn][30][2][2];
int a[maxn];
int n,k,x;
void solve()
{
cin>>n>>k>>x;
for (int i=1;i<=n;i++)
{
cin>>a[i];
}
for (int i=0;i<2;i++)
{
for (int j=0;j<2;j++)
{
dp[0][0][i][j]=0;
}
}
for (int i=1;i<=n;i++)
{
for (int j=0;j<=min(i,k);j++)
{
int t1=a[i]+x;
int t0=a[i]-x;
if (i>j)//最多只能有i-1个,他前面只有i-1个位置(不包括i),第i个进行减法操作
{
dp[i][j][0][0]=max(dp[i-1][j][0][0],max(dp[i-1][j][0][1],max(dp[i-1][j][1][0],max(dp[i-1][j][1][1],0ll))));
dp[i][j][0][1]=max(dp[i-1][j][0][1]+t0,max(dp[i-1][j][1][1]+t0,t0));
}
if (j)//加法操作,这一项的j可以等于i,可以前面到i都是加法
{
dp[i][j][1][0]=max(dp[i-1][j-1][0][0],max(dp[i-1][j-1][0][1],max(dp[i-1][j-1][1][0],max(dp[i-1][j-1][1][1],0ll))));
dp[i][j][1][1]=max(dp[i-1][j-1][0][1]+t1,max(dp[i-1][j-1][1][1]+t1,t1));
}
}
}
int ans=0;
for (int i=0;i<2;i++)
{
for (int j=0;j<2;j++)
{
ans=max(ans,dp[n][k][i][j]);
}
}
cout<<ans<<'\n';
return ;
}
signed main ()
{
int t;
cin>>t;
while (t--)
{
solve();
}
system ("pause");
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)