ABC-268解题报告
D. Unique Username
暴搜即可,复杂度
E. Chinese Restaurant (Three-Star Version)
个人感觉非常好的一道题。
首先抽象一下题意:
环形可以旋转,若一个人与和他编号相同的菜距离为
可以发现,有一些人用顺时针计算距离(如上图中的
计算人数的用处是什么呢?是转移。考虑一次也不转的情况下,贡献和可以暴力预处理出来。每当顺时针转一格,用顺时针计算距离的人的贡献会
细节:
code:
#include<bits/stdc++.h>
using namespace std;
#define int long long
int a[200010],t[400010],s[400010];
signed main() {
int n,ans=0,maxn;
cin>>n;
for(int i=0;i<n;i++) {
cin>>a[i];
ans+=min((a[i]-i+n)%n,(i-a[i]+n)%n);//暴力计算初始答案
t[(a[i]-i+n)%n]++,t[(a[i]-i+n)%n+n]++;//t数组复制两遍,拆环为链
}
for(int j=1;j<n+n;j++)
s[j]=s[j-1]+t[j];//前缀和
maxn=ans;//ans为当前答案,maxn为当前最优解
for(int i=1;i<n;i++) {//转i格后的答案
ans-=s[i+n/2-1]-s[i-1];//减顺时针
ans+=n-(s[i+n/2-1]-s[i-1]);//加逆时针
if(n%2) ans-=t[i+n/2];//特殊处理n为奇数的情况
maxn=min(maxn,ans);
}
cout<<maxn<<endl;
return 0;
}
F. Best Concatenation
每个字符串内部的贡献是永远不变的,于是预处理。之后,每个字符串的有用信息仅剩 “x
的数量
考虑相邻两个串什么时候需要交换。设它们为
若不交换,贡献为
code:
#include<bits/stdc++.h>
using namespace std;
#define int long long
struct node {
int numx,sum;
}a[200010];
signed main() {
int n,ans=0;
cin>>n;
for(int i=1;i<=n;i++) {
string s;
cin>>s;
int now=0;
for(int j=s.size()-1;j>=0;j--)
if(s[j]=='X') ans+=now,a[i].numx++;
else now+=s[j]-'0',a[i].sum+=s[j]-'0';
}
sort(a+1,a+n+1,[](node p,node q) {
return p.numx*q.sum>q.numx*p.sum;
});
int now=0;
for(int i=n;i>=1;i--)
ans+=a[i].numx*now,now+=a[i].sum;
cout<<ans<<endl;
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步