Codeforces Round #702 (Div. 3) 题解
A
分析:
直接模拟,对于相邻的两个数,如果小的两倍还是比大的小,就乘2,同时贡献++。
代码
#pragma GCC optimize("O3")
#include<bits/stdc++.h>
using namespace std;
#define SET0(a) memset(a,0,sizeof(a))
#define FOR(i,a,b) for(int i=(a);i<=(b);i++)
#define DWN(i,a,b) for(int i=(a);i>=(b);i--)
#define INF 0x3f3f3f3f
typedef long long ll;
int a[55];
int n;
int cal(int idx){
int maxv=max(a[idx],a[idx+1]);
int minv=min(a[idx],a[idx+1]);
int cnt=0;
while(minv*2<maxv) {minv*=2;cnt++;}
return cnt;
}
int main(){
int T; cin>>T;
while(T--){
cin>>n;
FOR(i,1,n) cin>>a[i];
int cnt=0;
FOR(i,1,n-1) cnt+=cal(i);
cout<<cnt<<endl;
}
return 0;
}
B
分析:
统计出 三种余数的个数。然后对小于 个数的多少进行分类讨论:
若个数为 ,即最小的个数也是 ,那么无需做任何操作。
若个数为 ,那么要让两个多的给那个少的补上,并统计贡献。
若个数为 ,那么要让多的给两个少的补上,并统计贡献。
即:
FOR(i,1,n){
cin>>a[i];
a[i]%=3;
cnt[a[i]]++;
}
int minv=INF;
FOR(i,0,2) minv=min(minv,cnt[i]);
if(minv==n/3){
cout<<0<<endl;
continue;
}
int res=0;
int cal=0;
FOR(i,0,2){
if(cnt[i]<n/3) cal++;
}
if(cal==1){
int idx;
FOR(i,0,2)
if(cnt[i]<n/3) idx=i;
res+=cnt[(idx+2)%3]-n/3 + 2*(cnt[(idx+1)%3]-n/3);
}
else if(cal==2){
int idx;
FOR(i,0,2)
if(cnt[i]>n/3) idx=i;
res+=n/3-cnt[(idx+1)%3] + 2*(n/3-cnt[(idx+2)%3]);
}
cout<<res<<endl;
代码
#pragma GCC optimize("O3")
#include<bits/stdc++.h>
using namespace std;
#define SET0(a) memset(a,0,sizeof(a))
#define FOR(i,a,b) for(int i=(a);i<=(b);i++)
#define DWN(i,a,b) for(int i=(a);i>=(b);i--)
#define INF 0x3f3f3f3f
typedef long long ll;
int a[30005];
int cnt[3];
int main(){
int T; cin>>T;
while(T--){
SET0(cnt);
int n; cin>>n;
FOR(i,1,n){
cin>>a[i];
a[i]%=3;
cnt[a[i]]++;
}
int minv=INF;
FOR(i,0,2) minv=min(minv,cnt[i]);
if(minv==n/3){
cout<<0<<endl;
continue;
}
int res=0;
int cal=0;
FOR(i,0,2){
if(cnt[i]<n/3) cal++;
}
if(cal==1){
int idx;
FOR(i,0,2)
if(cnt[i]<n/3) idx=i;
res+=cnt[(idx+2)%3]-n/3 + 2*(cnt[(idx+1)%3]-n/3);
}
else if(cal==2){
int idx;
FOR(i,0,2)
if(cnt[i]>n/3) idx=i;
res+=n/3-cnt[(idx+1)%3] + 2*(n/3-cnt[(idx+2)%3]);
}
cout<<res<<endl;
}
return 0;
}
C
分析:
预处理出 的所有立方数,问题即转化为求 是否存在两个数满足它们的和为目标数。
代码
#pragma GCC optimize("O3")
#include<bits/stdc++.h>
using namespace std;
#define SET0(a) memset(a,0,sizeof(a))
#define FOR(i,a,b) for(int i=(a);i<=(b);i++)
#define DWN(i,a,b) for(int i=(a);i>=(b);i--)
#define INF 0x3f3f3f3f
typedef long long ll;
const int N=1e4+5;
set<ll> rec;
void init(){
FOR(i,1,N)
rec.insert((ll)i*i*i);
}
int main(){
init();
int T; cin>>T;
while(T--){
ll x; cin>>x;
bool ok=0;
for(auto i:rec){
if(rec.find(x-i)!=rec.end()) ok=1;
}
if(ok) cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}
return 0;
}
D
分析:
分治,求出 中的最大值(根节点)所在下标 ,然后继续处理 , 的最大值(对应的下标即为 的左右节点),并且分别连边(建树)。
建树后从根节点跑一遍dfs求出每个节点深度即可。
代码
#pragma GCC optimize("O3")
#include<bits/stdc++.h>
using namespace std;
#define SET0(a) memset(a,0,sizeof(a))
#define FOR(i,a,b) for(int i=(a);i<=(b);i++)
#define DWN(i,a,b) for(int i=(a);i>=(b);i--)
#define INF 0x3f3f3f3f
typedef long long ll;
const int N=205;
int n;
int a[N];
struct node{
int to,next;
}e[N];
int head[N],tot;
void add(int u,int v){e[tot].to=v;e[tot].next=head[u];head[u]=tot++;}
int d[N];
int solve(int l,int r){
if(l==r) return r;
if(l>r) return -1;
int root;
FOR(i,l,r){
if(a[i]==*max_element(a+l,a+1+r)){
root=i;
break;
}
}
int ls=solve(l,root-1);
int rs=solve(root+1,r);
if(ls!=-1) add(root,ls);
if(rs!=-1) add(root,rs);
return root;
}
void dfs(int u,int deg){
d[u]=deg;
if(head[u]==-1) return;
for(int i=head[u];~i;i=e[i].next){
int go=e[i].to;
dfs(go,deg+1);
}
}
int main(){
int T; cin>>T;
while(T--){
tot=0;
memset(head,-1,sizeof head);
cin>>n;
FOR(i,1,n) cin>>a[i];
solve(1,n);
int root;
FOR(i,1,n)
if(a[i]==n) root=i;
dfs(root,0); // for depth
FOR(i,1,n) cout<<d[i]<<' ';
cout<<endl;
}
return 0;
}
E
分析:
排序,找到一个断点 ,使得即便是 的前缀和也比 a[idx]
小,那么 之前的玩家必然无法获胜。最后记录一下 的玩家编号即可。
代码
#pragma GCC optimize("O3")
#include<bits/stdc++.h>
using namespace std;
#define SET0(a) memset(a,0,sizeof(a))
#define FOR(i,a,b) for(int i=(a);i<=(b);i++)
#define DWN(i,a,b) for(int i=(a);i>=(b);i--)
#define INF 0x3f3f3f3f
typedef long long ll;
const int N=2e5+5;
struct node{
int id,v;
}a[N];
int b[N];
int n;
bool cmp(node a,node b){
return a.v<b.v;
}
ll s[N];
int main(){
int T; cin>>T;
while(T--){
cin>>n;
FOR(i,1,n){
cin>>a[i].v;
a[i].id=i;
}
sort(a+1,a+1+n,cmp);
FOR(i,1,n){
s[i]=s[i-1]+a[i].v;
}
int idx=1;
DWN(i,n,1){
if(s[i-1]<a[i].v){
idx=i;
break;
}
}
cout<<n-idx+1<<endl;
int cnt=0;
FOR(i,idx,n) b[cnt++]=a[i].id;
sort(b,b+cnt);
FOR(i,0,cnt-1) cout<<b[i]<<' ';
cout<<endl;
}
return 0;
}
F
分析:
记录一下每个数对应的个数,然后从大到小进行排序,枚举断点 , 的数表示不需要删到 , 的则全部删到 。最后统计贡献并求最小值。
代码
#pragma GCC optimize("O3")
#include<bits/stdc++.h>
using namespace std;
#define SET0(a) memset(a,0,sizeof(a))
#define FOR(i,a,b) for(int i=(a);i<=(b);i++)
#define DWN(i,a,b) for(int i=(a);i>=(b);i--)
#define INF 0x3f3f3f3f
typedef long long ll;
const int N=2e5+5;
int n;
int buc[N];
int main(){
int T; cin>>T;
while(T--){
map<int,int> f;
cin>>n;
FOR(i,1,n){
int k; cin>>k;
++f[k];
}
int tot=0;
for(auto i:f)
buc[++tot]=i.second;
sort(buc+1,buc+1+tot,greater<int>());
int ans=INF;
FOR(i,1,tot)
ans=min(ans,n-i*buc[i]);
cout<<ans<<endl;
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】