Codeforces Round #789 (Div. 2) A-C

比赛链接

A

题解

知识点:模拟。

(比较显然,不写了)

时间复杂度 O(nlogn)

空间复杂度 O(n)

代码

#include <bits/stdc++.h>
using namespace std;
int a[100];
int main(){
std::ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
int t;
cin>>t;
while(t--){
int n;
cin>>n;
for(int i = 0;i<n;i++){
cin>>a[i];
}
sort(a,a+n);
int cnt = 0;
bool ok = false;
for(int i = 0;i<n-1;i++){
if(a[i] == a[i+1] || !a[i]){
ok = true;
break;
}
}
for(int i = 0;i<n;i++){
if(a[i]) cnt++;
}
cout<<(cnt+!ok)<<'\n';
}
return 0;
}

B

题解

知识点:贪心。

对于给定偶数长度的0/1串,奇数子串与其他串(不论奇偶的其他)的分界点有且仅有一个位于某一对中间。比如,111001100011 划分以后变成 11,10,01,10,00,11 ,发现 111 的末尾 1 出现在 10 中,000 的首部 0 出现在 10 中。因此我们可以通过按对(即两个两个不相交)遍历,若遇到一次 0110 则操作次数加 1

与此同时,我们发现若修改一处 0110 可以修改成 0011 ,从而被前段或者后段的 0011 吸收不改变总段数,因此可以将修改等价认为直接删除这段 0110 ,即在程序中不考虑这种情况对总数影响,只需要记录 0011 的连续成段情况、特别地,如果 0/1 串本身没有 0011 的对,或者说全串由 0110 组成,那么它们可以自成唯一一段互相吸收,需要特判。

时间复杂度 O(n)

空间复杂度 O(n)

代码

#include <bits/stdc++.h>
using namespace std;
int main(){
std::ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
int t;
cin>>t;
while(t--){
int n;
cin>>n;
string s;
cin>>s;
int op = 0,cnt = 0;
char pre = '?';
for(int i = 0;i<n;i+=2){///两两配对
if(s[i] != s[i+1]) op++;///操作次数+1
else{
if(pre != s[i]) cnt++;///不同数字,段数+1
pre = s[i];///更新段数字
}
}
cout<<op<<' '<<max(1,cnt)<<'\n';///如果没有00/11吸收01/10,那么01/10可以自成一段
}
return 0;
}

C

题解

知识点:DP,枚举。

注意到 a<b<c<d ,可以考虑枚举 b,c 两个点,用 a,d 分别在 [1,b1][c+1,n] 的区间匹配。

匹配条件是 pa<pcpb>pd ,考虑用数组 cnt[i][j] 表示满足 pxj,x[1,i]x 个数。于是 a 的匹配个数是 cnt[b1][p[c]]d 的匹配个数是 cnt[n][p[b]]cnt[c][p[b]] 。因此,对于一组 b,c 可以得到 cnt[b1][p[c]](cnt[n][p[b]]cnt[c][p[b]]) 的组数,枚举 b,c 累加即可。

时间复杂度 O(n2)

空间复杂度 O(n2)

代码

#include <bits/stdc++.h>
using namespace std;
int p[5007],cnt[5007][5007];//注意初始化
int main(){
std::ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
int t;
cin>>t;
while(t--){
int n;
cin>>n;
for(int i = 1;i<=n;i++){
cin>>p[i];
}
for(int i = 1;i<=n;i++){///预处理cnt[i][j] 为 [1,i] 中小于等于 j 的数字个数
for(int j = 1;j<=n;j++) cnt[i][j] = cnt[i-1][j];///传递上个区间
for(int j = p[i];j<=n;j++) cnt[i][j]++;///j从p[i]开始都大于等于i,遍历+1
}
///枚举b,c,以此为准求[1,b-1]和[c+1,d]间合法a,d个数
long long ans = 0;
for(int b = 2;b<=n-2;b++){
for(int c = b+1;c<=n-1;c++){
ans += 1LL * cnt[b-1][p[c]] * (cnt[n][p[b]] - cnt[c][p[b]]);
}
}
cout<<ans<<'\n';
}
return 0;
}
posted @   空白菌  阅读(40)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
点击右上角即可分享
微信分享提示