Codeforces Round 1013 (Div. 3)(前5)
比赛链接
A:Olympiad Date
让我们开始一个数字计数器 cnt[i] ( 0≤i≤9) 3≤cnt[0],1≤cnt[1],2≤cnt[2], 1≤cnt[3],1≤cnt[5] 答案已找到。如果在计算所有数字之后,没有满足其中一个条件,则没有解决方案,答案为 0. 代码如下
#include <bits/stdc++.h>
using namespace std;
int main() {
int t;
cin >> t;
for (int test = 0; test < t; test++) {
int n;
cin >> n;
vector<int> a(n);
for (int i = 0; i < n; i++) {
cin >> a[i];
}
vector<int> cnt(10, 0);
bool found = false;
for (int i = 0; i < n; i++) {
cnt[a[i]]++;
if (cnt[0] >= 3 && cnt[1] >= 1 && cnt[2] >= 2 && cnt[3] >= 1 && cnt[5] >= 1) {
cout << i + 1 << endl;
found = true;
break;
}
}
if (!found) {
cout << 0 << endl;
}
}
return 0;
}
B. Team Training
为了最大化强队的数量,我们需要将学生按技能值从高到低排序,然后贪心地尽可能多地组成满足条件的队伍。具体步骤如下:
排序:将学生的技能值按降序排列,以便优先使用高技能的学生组成队伍。
贪心组队:遍历排序后的学生,维护当前可以组成的队伍数量(cnt)。当当前学生的技能值乘以当前队伍数量(a[i] * cnt)满足强度要求时,确认一个队伍,并重置计数器。
#include <iostream>
#include <algorithm>
using namespace std;
void solve() {
int n, x;
cin >> n >> x;
int a[n];
for (int i = 0; i < n; i++) {
cin >> a[i];
}
sort(a, a + n);
reverse(a, a + n);
int ans = 0;
for (int i = 0, cnt = 1; i < n; i++, cnt++) {
if (a[i] * cnt >= x) {
ans++;
cnt = 0;
}
}
cout << ans << endl;
}
int main() {
int t;
cin >> t;
while (t--) {
solve();
}
}
C. Combination Lock
规律如下

直接看出来
#include <iostream>
using namespace std;
void solve() {
int n;
cin >> n;
if (n % 2 == 0) {
cout << -1 << endl;
return;
}
for (int i = n; i > 0; i--) {
cout << i << ' ';
}
cout << endl;
}
int main() {
int t = 1;
cin >> t;
while (t--)
solve();
}
D. Place of the Olympiad
直接细节取整
#include<bits/stdc++.h>
#define IOS \
ios_base::sync_with_stdio(0); \
cin.tie(0); \
cout.tie(0);
#define ll long long
using namespace std;
ll mtt(ll n,ll m,ll k){
k=(k+n-1)/n;//向上取整
k=m/(m-k+1);//优化分配,向下取整,控制了每行最多能放多少个桌子,避免产生不均匀的分配
return k;
}
int main() {
IOS;
ll t;
cin >> t;
while (t--) {
ll n, m, k;
cin >> n >> m >> k;
cout << mtt(n, m, k) << '\n';
}
return 0;
}
二分
初始化:设左边界 left = 1,右边界 right = m。
计算中间值:每次循环计算区间中间值 mid = (left + right) / 2。
判断可行性:对于 mid,需计算在最长长椅长度为 mid 时场地能容纳的选手数,与 k 比较。
计算一行可容纳座位数:将每行座位按 mid + 1 个一组划分(前 mid 个为长椅,第 mid + 1 个为空分隔)。完整组数量为 m / (mid + 1),每组有 mid 个座位,完整组座位数为 (m / (mid + 1)) * mid。剩余座位数为 m % (mid + 1),这些也可成一个长椅。所以一行最多可放座位数为 seats_per_row = (m / (mid + 1)) * mid + (m % (mid + 1))。
计算全场可容纳选手数:场地有 n 行,全场最多容纳选手数 total_seats = seats_per_row * n。
更新区间:
若 total_seats >= k,说明 mid 可能是可行解,尝试更小长度,更新 right = mid - 1。
若 total_seats < k,说明 mid 太小,尝试更大长度,更新 left = mid + 1。
结束条件:当 left > right 时,二分查找结束,right + 1 即为所求最小的最长长椅长度。
#include <iostream>
using namespace std;
void solve() {
long long n, m, k, l, r, mid;
cin >> n >> m >> k;
l = 0, r = m;
while (l + 1 < r) {
mid = (l + r) / 2;
if ((m / (mid + 1) * mid + m % (mid + 1)) * n >= k) {
r = mid;
} else {
l = mid;
}
}
cout << r << endl;
}
int main() {
int t = 1;
cin >> t;
while (t--) {
solve();
}
}

浙公网安备 33010602011771号