2024.11.15 Codeforces Round 987(Div. 2)

Solved:5/6
Rank:74

比赛链接

A. Penchick and Modern Monument

给定一个不增序列,修改最少的数字使其不降。

全都修改为出现次数最多的数即可。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
void solve(){
int n;
cin>>n;
vector<int> a(n);
for(int& x:a)cin>>x;
int ans=1,len=1;
for(int i=1;i<n;++i){
if(a[i]==a[i-1])++len;
else len=1;
ans=max(ans,len);
}
cout<<n-ans<<'\n';
}
int main(){
ios::sync_with_stdio(0);cin.tie(0);
int T;
cin>>T;
while(T--)solve();
}

B. Penchick and Satay Sticks

给定一个排列,只能交换位置和值都相邻的数,问能否排成有序

注意到这种规则下每个数最多移动一个位置,因此如果存在 |aii|>1 就直接无解。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
bool solve(){
int n;
cin>>n;
vector<int> a(n);
for(int& x:a)cin>>x,--x;
for(int i=0;i<n;++i)if(abs(a[i]-i)>1)return 0;
return 1;
}
int main(){
ios::sync_with_stdio(0);cin.tie(0);
int T;
cin>>T;
while(T--)cout<<(solve()?"YES":"NO")<<'\n';
}

C. Penchick and BBQ Buns

给定 n,构造一个正整数序列,使得出现过的数字都至少出现两次,且任意两个相同数字的距离均为平方数。

n 为偶数时,{1,1,2,2,,n2,n2} 即满足条件。

n 为奇数时,必然存在一个数出现至少三次。即 p2p1,p3p2,p3p1 同时为完全平方数。满足这个条件最小的一组数是 9,16,25。因此 n25 无解。

另一方面,n=27容易构造出 {1,2,2,3,3,4,4,5,5,1,6,6,7,7,8,8,9,9,10,10,11,11,12,13,13,1,12} 满足条件。

因此 n27 均有解,后面和偶数一样填数就行。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
void solve(){
int n;
cin>>n;
if(!(n&1)){
for(int i=1;i<=n/2;++i)cout<<i<<' '<<i<<' ';
cout<<'\n';
}
else{
if(n<27)cout<<"-1\n";
else{
cout<<"1 2 2 3 3 4 4 5 5 1 6 6 7 7 8 8 9 9 10 10 11 11 12 13 13 1 12 ";
for(int i=14;i*2+1<=n;++i)cout<<i<<' '<<i<<' ';
cout<<'\n';
}
}
}
int main(){
ios::sync_with_stdio(0);cin.tie(0);
int T;
cin>>T;
while(T--)solve();
}

D. Penchick and Desert Rabbit

n 棵树,从第 i 棵树出发,每次可以跳到右边更矮的树或者左边更高的树。对所有起点,求能跳到的最高的树。

每个点的答案一定是一个前缀 max,且跳的过程会被挡住当且仅当存在某个 i 使得 maxj=1iajminj=i+1naj

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
void solve(){
int n;
cin>>n;
vector<int> a(n+1);
for(int i=1;i<=n;++i)cin>>a[i];
vector<int> mx(n+2),mn(n+2);
mx[0]=0,mn[n+1]=1e9;
for(int i=1;i<=n;++i)mx[i]=max(mx[i-1],a[i]);
for(int i=n;i>=1;--i)mn[i]=min(mn[i+1],a[i]);
for(int i=1,j=1;i<=n;++i){
if(mx[i]<=mn[i+1]){
while(j<=i)cout<<mx[i]<<' ',++j;
}
}
cout<<'\n';
}
int main(){
ios::sync_with_stdio(0);cin.tie(0);
int T;
cin>>T;
while(T--)solve();
}

E. Penchick and Chloe's Trees

给一棵树,已知这棵树由一棵完全二叉树缩点生成,求这棵完全二叉树的最小深度。

树形 dp,设 fu 表示 u 的子树缩点前的最小深度。

假设已知 u 的全体儿子的深度。考虑贪心,每次找到深度最小的两棵子树(设为 d)合并成 d+1 的子树。

这就是二进制加法的过程。即 fu=log2(v2fv)

暴力模拟二进制加法即可。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e6+5;
int n,x,f[N];
vector<int> e[N];
int t[N];
void dfs(int u){
int mx=0,cnt=0;
for(int v:e[u])dfs(v);
vector<int> buc;
for(int v:e[u]){
int x=f[v];
if(!t[x])++cnt;
++t[x];
buc.push_back(x);
while(t[x]==2){
t[x]=0,--cnt;
if(!t[x+1])++cnt;
++t[++x],buc.push_back(x);
}
mx=max(mx,x);
}
for(int x:buc)t[x]=0;
f[u]=mx+(cnt>1)+(e[u].size()==1);
}
void solve(){
cin>>n;
for(int i=1;i<=n;++i)e[i].clear(),f[i]=0;
for(int i=2;i<=n;++i)cin>>x,e[x].push_back(i);
dfs(1);
cout<<f[1]<<'\n';
}
int main(){
ios::sync_with_stdio(0);cin.tie(0);
int T;
cin>>T;
while(T--)solve();
}
posted @   EssnSlaryt  阅读(205)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示