Codeforces Round 954 (Div. 3)
T1,T2水题,没啥好说的。T3半水题,T4赛时唐氏,T5有一点想不到。
T3 Update Queries
题意
给一个长度为
你可以任意更改字符串
求
解析
一眼看上去有点麻烦,想一想发现对于同一个
又因为
#include<bits/stdc++.h>
using namespace std;
#define LL long long
const int N = 1e5+5;
int t;
int n,m,a[N];
bool vs[N];
string s,c;
int main()
{
scanf("%d",&t);
while(t--)
{
memset(vs,0,sizeof(vs));
scanf("%d%d",&n,&m);
cin>>s; s=' '+s;
for(int i=1;i<=m;i++) scanf("%d",&a[i]);
cin>>c; c=' '+c;
sort(a+1,a+1+m);
sort(c.begin(),c.end()); int l=1;
for(int i=1;i<=m;i++)
{
if(vs[a[i]]) continue;
s[a[i]]=c[l++]; vs[a[i]]=1;
}
for(int i=1;i<=n;i++) printf("%c",s[i]);
puts("");
}
return 0;
}
T4 Mathematical Problem
题意
给一个长度为
注意
运算式的结果是根据数学规则计算的——首先进行所有乘法运算,然后进行加法运算。请你找到最小的结果。
解析
赛时唐氏,一眼数据范围然后开始区间 dp,更唐氏的是赛时暴力处理乘积,
赛后优化到
code
#include<bits/stdc++.h>
using namespace std;
#define LL long long
const int N = 25;
int t,n,a[N];
LL f[N][N],ans;
int work()
{
int b[N]; ans=1e9;
for(int i=1;i<n;i++)
{
memset(f,0x3f,sizeof(f));
int o=1,p=1;
while(o<=n)
{
if(o==i) b[o]=a[p]*10+a[p+1],p+=2;
else b[o]=a[p++]; o++;
}
for(int j=1;j<n;j++) f[j][j]=b[j];
for(int len=2;len<n;len++)
{
for(int l=1,r=l+len-1;r<n;r++,l++)
{
LL tmp=1;
for(int k=l;k<=r;k++)
{
tmp*=b[k];
if(k==r) f[l][r]=min(f[l][r],tmp);
else f[l][r]=min(f[l][r],tmp+f[k+1][r]);
if(tmp>ans) break;
}
}
}
ans=min(ans,f[1][n-1]);
}
return ans;
}
int main()
{
scanf("%d",&t);
while(t--)
{
scanf("%d",&n); bool fl=0;
for(int i=1;i<=n;i++) scanf("%1d",&a[i]),fl|=(!a[i]);
if(fl&&n>3) puts("0");
else printf("%d\n",work());
}
return 0;
}
正解是贪心,因为要放
对于得到的
注意如果全是
#include<bits/stdc++.h>
using namespace std;
const int N = 21;
int t,n,a[N],b[N];
int work()
{
int ans=1e9;
for(int i=1;i<n;i++)
{
int res=0;
for(int j=1,p=1;j<n;j++,p++)
{
if(p==i) b[j]=a[p]*10+a[p+1],p++;
else b[j]=a[p];
}
for(int j=1;j<n;j++)
{
if(b[j]==0) return 0;
if(b[j]!=1) res+=b[j];
}
res=max(1,res);
ans=min(ans,res);
}
return ans;
}
int main()
{
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%1d",&a[i]);
if(n==2) printf("%d\n",a[1]*10+a[2]);
else printf("%d\n",work());
}
return 0;
}
T5 Beautiful Array
题意
给
现在你可以将这
如果不能输出
回文序列定义为
解析
我们按模数分组(需要离散化),如果两个数
因此我们分类后排序,每组相邻的两个数之差
要求最多有一组个数为奇数,才能满足一一配对,否则不可能满足。
问题在奇数时,因为奇数中间的数不用配对,所以我们在计算时应该删掉一个。
问题就是去掉哪一个数最优,首先,这个数一定是排序后奇数位上的数。
然后我们先假定去掉这一组中的第一个数,计算出一个值。
每一次更改其实就是进行
变成
因此我们可以
#include<bits/stdc++.h>
using namespace std;
#define LL long long
const int N = 1e5+5;
int t;
int n,k,a[N];
vector<int> v[N];
map<int,int> mp;
int main()
{
scanf("%d",&t);
while(t--)
{
LL ans=0;
int tot=0;
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
int tmp=a[i]%k;
if(mp.find(tmp)==mp.end()) mp[tmp]=++tot;
v[mp[tmp]].push_back(a[i]);
}
int fl=0;
for(int i=1;i<=tot;i++)
{
sort(v[i].begin(),v[i].end());
if(v[i].size()&1)
{
fl++;
if(fl==2)
{
puts("-1");break;
}
LL tmp=0;
for(int j=2;j<v[i].size();j+=2) tmp+=(v[i][j]-v[i][j-1])/k;
LL res=tmp;
for(int j=1;j<v[i].size();j+=2)
{
tmp=tmp-(v[i][j+1]-v[i][j])/k+(v[i][j]-v[i][j-1])/k;
res=min(res,tmp);
}
ans+=res;
}
else
for(int j=1;j<v[i].size();j+=2) ans+=(v[i][j]-v[i][j-1])/k;
}
if(fl<2) printf("%lld\n",ans);
for(int i=1;i<=tot;i++) v[i].clear();
mp.clear();
}
}
CF 不能用 unordered_map
据 qinyun 悲惨经历,CF 用 unordered_map
真的会被
unordered_map
实现原理是哈希表,有一个固定的模数。。。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· 清华大学推出第四讲使用 DeepSeek + DeepResearch 让科研像聊天一样简单!
· 实操Deepseek接入个人知识库
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库