Codeforces Round 983 (Div. 2) 10.31 ABC题解
Codeforces Round 983 (Div. 2) 10.31 题解
A. Circuit
数学(math)贪心(greedy)模拟(implementation)题意:
有
给出
输入:
第一行一个整数
每组第一行一个整数
第二行
输出:
每组一行,两个整数,分别表示打开灯可能的最小数量和最大数量。
样例输入:
5
1
0 0
1
0 1
1
1 1
3
0 0 1 0 1 0
3
0 1 1 1 0 0
样例输出:
0 0
1 1
0 0
0 2
1 3
样例解释:
第一个样例中,开关都是关的,所以开灯最少最多都是
第二个样例中,有一个开关是开的,所以这盏灯一定是亮的,所以开灯最少跟最多都是
在第三个样例中,两个开关都是开的,表示一开一关,这个时候这盏灯是关着的,所以开灯最少跟最多都是
在第四个样例中,有两个开关是打开的,如果他们对应同一盏灯,那么这个灯会熄灭,所以最少为
分析:
我们发现,开关关闭对于结果并无影响。
所以首先需要统计开关打开的数量
先求开灯最少数:
我们可以发现,当
相反,如果
再求最大值,我们可以得到,如果开
但是如果
ac 代码:
#include <bits/stdc++.h>
using namespace std;
int T,n,m;
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin>>T;
while(T--){
cin>>n;
int cnt=0;
for(int i=0;i<2*n;i++){
cin>>m;
cnt+=m;
}
int min_=0,max_=0;
if(cnt%2)min_=1;
else min_=0;
if(cnt>n){
max_=2*n-cnt;
}
else max_=cnt;
cout<<min_<<" "<<max_<<endl;
}
return 0;
}
B. Medians
贪心(greedy)模拟(implementation)题意:
给定一个整数
我们需要将这个序列划分成奇数个序列,每个序列含有奇数个元素,并且每个序列的中位数组成的新序列的中位数等于
中位数:数组排序后中间的元素,例如:序列
这里定义的划分是连续元素的划分。
输出合理划分的子数组个数,以及每个子数组左端开头的元素。
如果不存在这样的划分,输出
输入:
第一行一个整数
每组数据一行两个整数
输入限制:
输出:
每组两行,第一行一个整数
第二行
样例输入:
4
1 1
3 2
3 3
15 8
样例输出:
1
1
3
1 2 3
-1
5
1 4 7 10 13
样例解释:
第一个样例中,划分成的子数组只能是
第二个样例中,可以化分成三个数组
第三个样例中,我们可以证明,不管怎么划分,最后都不可能得到子数组中位数组成序列的中位数是
第四个样例中,可以划分出的子数组为
分析:
由于此题存在无解的情况。我们首先考虑什么时候无解。
我们很容易想到,中位数定义是排序后中间的元素,所以不论如何划分,端点元素一定无法成为中位数。
所以如果是
再分析有解的情况:
我们可以很容易发现,我们划分数组可以分为三个,小于
由于我们划分成的子数组必须是奇数,所以我们还需要考虑
我们很容易发现,
那么我们可以直接划分
相反,如果
我们很容易想到前面拿一个元素,后面也拿一个元素,这样前面一部分可以实现,后面一部分也同样可以实现了。
ac 代码:
#include <bits/stdc++.h>
using namespace std;
int T,n,k;
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin>>T;
while(T--){
cin>>n>>k;
if(n == 1){
cout<<1<<endl;
cout<<1<<endl;
}
else if(k==1||k==n){
cout<<-1<<endl;
}
else{
if(k%2==0){
cout<<3<<endl;
cout<<1<<" "<<k<<" "<<k+1<<endl;
}
else {
cout<<3<<endl;
cout<<1<<" "<<k-1<<" "<<k+2<<endl;
}
}
}
return 0;
}
C. Trinity
二分(binary search)双指针(two pointers)排序(sortings)题意:
给定一个大小为
可以有如下操作,每次选择一个位置
操作若干次后,需要让数组内任意三个元素大小满足一个三角形。即
求这样操作的最少次数。
输入:
第一行一个整数
每组第一行一个整数
第二行
输出:
每组输出一个整数表示操作的最少次数。
样例输入:
4
7
1 2 3 4 5 6 7
3
1 3 2
3
4 5 3
15
9 3 8 1 6 5 3 8 2 1 4 2 9 4 7
样例输出:
3
1
0
8
样例分析:
第一个样例中,可以将数组首先变为
第二个样例可以将数组变为
第三个样例,三个元素已经可以构成三角形了,不需要操作。
分析:
我们发现数组内元素可以任意变化而不需要考虑位置,所以我们先排序。
我们对于有序数组,需要满足三个元素构成三角形,那么有
我们这时发现,我们仅仅需要考虑他变化的最少个数就是满足前两个元素的和大于第三个元素最大序列长度。
我们很容易得到这个长度可以通过二分来得到。
ac 代码:
#include <bits/stdc++.h>
using namespace std;
const int N=200010;
#define int long long
int a[N];
int T,n;
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin>>T;
while(T--){
cin>>n;
for(int i=1;i<=n;i++)cin>>a[i];
sort(a+1,a+n+1);
int ans=0x3f3f3f3f3f3f3f3f;
for(int i=1;i<n;i++){
int tmp=a[i]+a[i+1];
int l=i+1,r=n;
int k=i;
while(l<=r){
int mid=l+r>>1;
if(a[mid]<tmp){
k=mid;
l=mid+1;
}
else r=mid-1;
}
ans=min(ans,n-k+i-1);
}
cout<<ans<<endl;
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】