Codeforces Round #848 (Div. 2)(B,C,D)
Codeforces Round #848 (Div. 2)(B,C,D)
哎呀,最近不知道怎么回事,题目老是没看懂,还是心不在此,太烦了,好几天都只是一道题了
B
这道题到看答案才发现我理解错了,我怎么说越想越复杂,我就说第二道题怎么会这么复杂
其实题目的意思是要求我们每一个都满足条件才是
现在我看完了题解,发现我的题都读错了,真离谱
这道题大意是
给你一个长度为
即 对于
我们要求的是要这个数组变成
移动是什么?
移动可以改变排序
所以我们只有一个不满足以上
如果每一个都满足
对于此时
第一种,让
第二种,是让
然后我们取较小的那一个移动次数
#include <iostream>
#include <string>
using namespace std;
const int maxn=1e5+10;
int t,n,d,m;
int pos[maxn],k;
int a[maxn];
void solve()
{
cin>>n>>m>>d;
for (int i=1;i<=n;i++)
{
int x;
cin>>x;
pos[x]=i;
}
int ans=1e9;
for (int i=1;i<=m;i++)
{
cin>>a[i];
}
for (int i=1;i<m;i++)
{
if (pos[a[i]]<pos[a[i+1]]&&pos[a[i+1]]<=pos[a[i]]+d)
{
int c1=pos[a[i+1]]-pos[a[i]];//交换两个位置,让pos[a[i]]>pos[a[i+1]]
int c2=1e9;
if (d<n-1)//n-1是这两个数的最远距离,n-1,只有两点距离大于d才可以满足这第二个情况,pos[a[i+1]]>pos[a[i]]+d,那么这个d只能小于n-1才可
{
c2=pos[a[i]]+d+1-pos[a[i+1]];
}
int c=min(c1,c2);
ans=min(ans,c);
}
else
{
cout<<0<<'\n';
return ;
}
}
cout<<ans<<'\n';
return ;
}
signed main ()
{
cin>>t;
while (t--)
{
solve();
}
system ("pause");
return 0;
}
C
这个题大意是给你两个字符串
我们可以实行任意次操作
把
对于这个限制,我们首先可以把所有需要改变的字符
然后我们可以看到题目中那个加粗字,
每一个状态都代表着其中的一类字符的改变还是保留的情况
对于这一类的字符,如果需要是改变成
那么怎么求
对于如果有一段长度为
对于不同的
然后对于不同的状态,我们选取那个可以得到最大的对数的那一个状态
#include <iostream>
#include <string>
#include <vector>
using namespace std;
#define int long long
int t,n,k;
string a,b;
void solve()
{
cin>>n>>k;
cin>>a>>b;
vector<int>vis(30,0);
vector<int>code(30,0);
int cnt=0;
for (int i=0;i<n;i++)
{
vis[a[i]-'a']=1;
}
for (int i=0;i<26;i++)
{
if (vis[i])
{
code[cnt++]=i;
}
}
k=min(k,cnt);
int M=1<<cnt;
int ans=0;
for (int i=0;i<M;i++)
{
vector<bool>use(26,false);
int tot=0;
for (int j=0;j<cnt;j++)
{
if ((i>>j)&1)
{
use[code[j]]=true;
tot++;
}
}
if (tot==k)
{
string tmp=a;
for (int j=0;j<n;j++)
{
if (use[tmp[j]-'a'])
{
tmp[j]=b[j];
}
}
int tot=0;
int sum=0;
for (int j=0;j<n;j++)
{
if (tmp[j]==b[j])
{
tot++;
}
else
{
sum+=tot*(tot+1ll)/2;
tot=0;
}
if (j==n-1)
{
sum+=tot*(tot+1ll)/2;
}
}
ans=max(ans,sum);
}
}
cout<<ans<<'\n';
return ;
}
signed main ()
{
cin>>t;
while (t--)
{
solve();
}
system ("pause");
return 0;
}
D
这个题大意是我们有两种
问最后把
我们可以定义
状态转移是怎么转移的
这个是怎么来的呢
对于此时已经有
如果这一次我们直接选择那些不相同的位置进行翻转,那么已经有
如果这一次我们选择那些相同的位置的字符翻转,那么此时相同的位置就变成了了
但是我们最好是把未知数放在同一边,所以我们可以在纸上进行变换
可以得到以下这个方程
然后我们从原来有
#include <iostream>
#include <string>
using namespace std;
#define int long long
const int mod=998244353;
const int maxn=1e6+10;
int t,n;
string a,b;
int f[maxn];
int ksm(int x,int p)
{
int res=1;
while (p)
{
if (p&1)
{
res=(res*x)%mod;
}
x=(x*x)%mod;
p>>=1;
}
return res%mod;
}
int inv(int x)
{
return ksm(x,mod-2);
}
void solve()
{
cin>>n;
cin>>a>>b;
int cnt=0;
for (int i=0;i<n;i++)
{
if (a[i]==b[i])
{
cnt++;
}
}
f[1]=1;
for (int i=1;i<n;i++)
{
f[i+1]=(1+i*inv(n-i)%mod*(f[i]+1))%mod;
}
int ans=0;
for (int i=cnt+1;i<=n;i++)
{
ans=(ans+f[i])%mod;
}
ans%=mod;
cout<<ans<<'\n';
return ;
}
signed main ()
{
cin>>t;
while (t--)
{
solve();
}
system ("pause");
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)