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();
    }
    
}
posted @ 2025-03-30 16:58  fufuaifufu  阅读(23)  评论(0)    收藏  举报