Educational Codeforces Round 131 (Rated for Div. 2) ABCD

Educational Codeforces Round 131 (Rated for Div. 2)

https://codeforces.com/contest/1701

A. Grass Field

统计1的个数cnt:

  1. cnt=0,则ans=0
  2. 0<cnt<4,则ans=1
  3. cnt=4,则ans=2
    (直接加起来也行,这里写的不是很优雅)
#include <bits/stdc++.h>

using namespace std;

void solve () {
    int x, cnt = 0;
    for (int i = 0; i < 4; i ++) {
        cin >> x;
        if (x == 1) cnt ++;
    }
    if (cnt == 0)   cout << "0\n";
    else if (cnt < 4)   cout << "1\n";
    else    cout << "2\n";
}

int main () {
    int t;
    cin >> t;
    while (t --)    solve ();
}

B. Permutation

d=2时,一定最优。因为长度固定的情况下,2的指数次增长比其他数字都慢。考虑如何构造:
一开始想的是按照质数的倍数来筛,但是诸如30(235)就没法构造进去。。
所以还是直接暴力构造吧(允悲)

#include <bits/stdc++.h>

using namespace std;
const int N = 2e5+5;
int a[N+5];

// bool is_prime (int x) {
//     if (x == 1) return true;
//     if (x == 2) return false;
//     for (int i = 2; i*i <= x; i ++)
//         if (x%i == 0)   return false;
//     return true;
// }

// void pre () {
//     int k = 1;
//     for (int i = 1; i <= N; i ++)
//         if (is_prime (i))   a[k++] = i;   
// }

void solve () {
    int n;  cin >> n;
    cout << "2\n";
    //int res = n;
    bitset<N>vis;
    for (int i = 1; i <= n; i ++) {
        if (vis[i]) continue;
        for (int j = i; j <= n; j *= 2) 
            vis[j] = true, cout << j << ' ';
    }
    cout << endl;
}

int main () {
    //pre();
    int t;
    cin >> t;
    while (t --)    solve ();
}
//d=2时最优
//先预处理

C. Schedule Management

二分答案(考虑性质:最大时间最小)(工作是同时进行的)

#include <bits/stdc++.h>
#define int long long

using namespace std;
const int N = 2e5 + 5;
int a[N];
int n, m;

bool check (int x) {
    int time = 0, need = 0;  
    for (int i = 1; i <= n; i ++) {
        if (a[i] >= x)  need += a[i] - x; //人手足够
        else    time += (x - a[i]) / 2; //要派x-a[i]个人来额外协助,这部分人用过了,所以除2
    }
    return time >= need;
}

void solve () {
    memset (a, 0, sizeof a);
    cin >> n >> m; //工人数,任务数
    set<int> s;
    for (int i = 1; i <= m; i ++) {
        int x; cin >> x;
        a[x] ++; //该工人可以胜任多少份工作
        s.insert (x);
    }   
    //每个工作都由不同的人负责
    if (s.size () == m) {
        cout << "1\n";
        return ;
    }

    int l = 1, r = 2 * m + 1;
    while (l < r) {
        int mid = l + r >> 1;
        if (check (mid))    r = mid;
        else    l = mid + 1;
    }
    cout << l << endl;

}

signed main () {
    int t;
    cin >> t;
    while (t --)    solve ();
}

//二分答案

//dp
//f[i][j]:当前进行到第i个任务,选择编号为j的工人
//维护一个vis[N],表示当前工人是否可用

//贪心
//排序,统计每个连续段个数
//把每个所需时间放进来

D. Permutation Restoration

已知bi=iai (下取整),给定bi,要还原数列a[]
解:

b[i]ia[i]<b[i]+1ib[i]+1<a[i]ib[i]

(b[i]=0,ib[i]=n)

然后枚举i为要放置的数

根据贪心的策略,每次都选择最小的右端点R(能放下更多的数)

故把满足Li的区间[L,R]放入堆中,然后每次取出最小的R即可

(代码参考ygg)

#include <bits/stdc++.h>

using namespace std;
typedef pair<int, int> pii;
const int N = 5e5 + 5;
int a[N], b[N];

void solve () {
    int n;  cin >> n;
    
    vector <pii> v[n+1];
    for (int i = 1; i <= n; i ++) {
        cin >> b[i];
        int L = i / (b[i] + 1) + 1; //要再+1,因为左端点取不到等号
        int R = b[i] == 0 ? n : i/b[i];
        v[L].push_back ({R, i}); //方便按照数轴顺序来提取区间
    }

    priority_queue <pii, vector <pii>, greater<pii>> q; //存最近R的区间堆
    for (int i = 1; i <= n; i ++) {
        for (auto j : v[i]) q.push (j);
        auto t = q.top();
        q.pop();
        a[t.second] = i;
    }

    for (int i = 1; i <= n; i ++)   cout << a[i] << ' ';
    cout << endl;
}

int main () {
    int t;
    cin >> t;
    while (t --)    solve ();
}

E. Text Editor

F. Points

posted @   Sakana~  阅读(50)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示