【CodeForces训练记录】Educational Codeforces Round 176 (Rated for Div. 2)
训练情况

赛后反思
edu场拉闸,A题写了个暴力白罚一次,之后五分钟速切,B题卡了两个小时成功倒闭,被数据范围诈骗到了,C题1500是赛后才会做的
A题
首先我们显然知道,奇数-奇数=偶数,偶数-偶数=偶数,因为要操作次数最小,对于给出的 \(k\) 去求它的最大奇数和最大偶数,如果 \(n\) 是奇数,先把 \(n\) 变成偶数同时答案加一,剩下就是偶数一直操作了,减多少次当然就是除法操作了
点击查看代码
#include <bits/stdc++.h>
// #define int long long
#define endl '\n'
using namespace std;
void solve(){
int n,k; cin>>n>>k;
int ans = 0;
int ji,ou;
if(k&1) ji=k,ou=k-1;
else ji=k-1,ou=k;
if(n&1) n-=ji,ans++;
ans += (n+ou-1)/ou;
cout<<ans<<endl;
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
int T; cin>>T; while(T--)
solve();
return 0;
}
B题
刚开始想的是枚举最后一个被涂色的位置,然后左右两边求最大 \(k\) 个数求和,复杂度是 \(O(n^2 \log n)\),很符合题目的数据范围,但是转头一下发现这题还有更简单的做法,首先对于 \(k=1\) 的情况,显然最后一个被涂色的位置只能是两端,初始涂色的位置当然就是除两端外的最大值,对于 \(k>1\) 的情况,我们显然最后答案的贡献为 \(k+1\) 个方格之和,想要答案最大我们直接选择最大的 \(k+1\) 个数,我们显然能保证至少存在一种涂色方法能实现,因为我们初始选择的时候就选最靠左边的最大数和最靠右边的,这样保证剩下最后一个涂色的一定在中间,这样肯定存在一个方法能使那个方格最后涂色,所以我们直接 \(k=1\) 和 \(k>1\) 进行分类讨论即可
点击查看代码
#include <bits/stdc++.h>
#define int long long
#define endl '\n'
using namespace std;
void solve(){
int n,k; cin>>n>>k;
vector<int> a(n + 1);
for(int i = 1;i<=n;i++) cin>>a[i];
if(k == 1){
cout<<max(a[1] + *max_element(a.begin() + 2,a.end()),a[n] + *max_element(a.begin() + 1,a.end() - 1))<<endl;
return;
}
sort(a.begin() + 1,a.end(),greater<int>());
int ans = 0;
for(int i = 1;i<=min(n,k+1);i++) ans+=a[i];
cout<<ans<<endl;
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
int T; cin>>T; while(T--)
solve();
return 0;
}
C题
我们能选择两种颜色涂色,左边一坨和右边一坨长度和要为 \(n\),所以我们考虑枚举其中一端的长度,另一端的长度显然就知道了,剩下从 \(m\) 个颜色中做出选择,显然我们能选择 \(\le\) 的颜色,显然我们排序后 lower_bound 二分查找,找出来的位置一直到 \(m\) 的区间都是合法答案,由于是两个颜色,选法就是乘法原理,但是对于如果找出来的两个区间有重叠,重叠会导致选择的两个颜色一样,我们需要容斥一下去掉重复计算的答案,就是减去区间长度的最小值就是重复的区间长度
点击查看代码
#include <bits/stdc++.h>
#define int long long
#define endl '\n'
using namespace std;
void solve(){
int n,m; cin>>n>>m;
vector<int> a(m + 1);
for(int i = 1;i<=m;i++) cin>>a[i];
sort(a.begin() + 1,a.end());
int ans = 0;
for(int i=1;i<n;i++) {
auto it1 = lower_bound(a.begin() + 1,a.end(),i);
auto it2 = lower_bound(a.begin() + 1,a.end(),n - i);
if (it2 == a.begin()) continue;
ans += (m - (it1 - a.begin()) + 1) * (m - (it2 - a.begin()) + 1);
ans -= min(m - (it1 - a.begin()) + 1, m - (it2 - a.begin()) + 1);
}
cout<<ans<<endl;
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
int T; cin>>T; while(T--)
solve();
return 0;
}

浙公网安备 33010602011771号