首页 > 其他分享 >Educational Codeforces Round 149 (Rated for Div. 2)

Educational Codeforces Round 149 (Rated for Div. 2)

时间:2023-05-30 21:56:27浏览次数:40  
标签:Educational Rated return int Codeforces long else ++ cnt

A. Grasshopper on a Line

#include <bits/stdc++.h>

using namespace std;

#define int long long

void solve(){
    int x , k;
    cin >> x >> k;
    if( x % k == 0 ){
        cout << "2\n" << x - 1 << " " << 1 << "\n";
    }else{
        cout << "1\n" << x << "\n";
    }
}

int32_t main() {
    ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
    int t;
    cin >> t;
    while( t -- )
        solve();

        return 0;

}

B. Comparison String

直接找到连续相同且最长的段即可。

#include <bits/stdc++.h>

using namespace std;

#define int long long

void solve(){
    int n;
    string s;
    cin >> n >> s;
    int res = 0 , last = '.', cnt = 0;
    for( auto i : s ){
        if( last == i ) cnt ++;
        else{
            last = i , cnt = 1;
        }
        res = max( res , cnt );
    }
    cout << res + 1<< "\n";
    return ;
}

int32_t main() {
    ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
    int t;
    cin >> t;
    while( t -- )
        solve();

    return 0;

}

C. Best Binary String

连续的问号和两端的任意一个相同即可。

#include <bits/stdc++.h>

using namespace std;

#define int long long

void solve() {
    int n;
    string s;
    cin >> s;
    n = s.size();
    if( s[0] == '?' ) s[0] = '0';
    if( s[n-1] == '?' ) s[n-1] = '1';
    for( int i = 1 ; i < n-1 ; i ++ ){
        if( s[i] == '?' ){
            int j = i;
            while( s[j] == '?' ) j ++;
            if( s[i-1] == '1' && s[j] == '1' )
                for( int l = i ; l < j ; l ++ ) s[l] = '1';
            else
                for( int l = i ; l < j ; l ++ ) s[l] = '0';
            i = j;
        }
    }
    cout << s << "\n";


    return;
}

int32_t main() {
    ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
    int t;
    cin >> t;
    while (t--)
        solve();

    return 0;

}

D. Bracket Coloring

跑两种括号匹配,然后正序的括号匹配染成一种颜色,反序的括号匹配染成另一种颜色即可。

#include <bits/stdc++.h>

using namespace std;

#define int long long

void solve() {
    int n;
    string s;
    cin >> n >> s;
    if (n & 1) {
        cout << "-1\n";
        return;
    } else {
        int a = 0, b = 0;
        for (auto i: s)
            if (i == '(') a++;
            else b++;
        if (a != b) {
            cout << "-1\n";
            return;
        }
    }
    n = s.size();
    int cnt = 0, st = -1, p = 0;
    vector<pair<int, int>> res;
    for (auto i: s) {
        if (i == '(') {
            if (st == -1) st = 1, cnt = 1, p = 1;
            else if (st == 1) cnt++, p++;
            else if (cnt == 0) {
                res.emplace_back(st, p);
                st = 1, cnt = 1, p = 1;
            } else cnt--, p++;
        } else {
            if (st == -1) st = 2, cnt = 1, p = 1;
            else if (st == 2) cnt++, p++;
            else if (cnt == 0) {
                res.emplace_back(st, p);
                st = 2, cnt = 1, p = 1;
            } else cnt--, p++;
        }
    }
    res.emplace_back( st , p );
    if( res.size() == 1 ){
        cout << "1\n";
        for( int i = 1 ; i <= n ; i ++ )
            cout << "1 ";
        cout << "\n";
        return;
    }
    cout << "2\n";
    for (auto [a, b]: res) {
        while (b) cout << a << " ", b--;
    }
    cout << "\n";

    return;
}

int32_t main() {
    ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
    int t;
    cin >> t;
    while (t--)
        solve();

    return 0;
}

E. Playoff Fixing

首先对于某回合中那些人输其实是固定的,比如\(k=3\)时,赢的人一定是\(1,2,3,4\)输的人一定是\(5,6,7,8\)

这样的话,要保证每一对中必须是一个前一半的和一个后一半的。这样的话只需要统计出后一半需要放的人是数量\(cnt\)这样就有\(cnt!\)种情况。如果出现一组中是\(-1,-1\)的情况,那就可以颠倒顺序,统计出可以颠倒顺序的组的数量\(p\),然后就可以知道对于当前回合的方案数\(cnt!\times2^p\),然后再递归的计算下一个回合即可。

#include <bits/stdc++.h>

using namespace std;

#define int long long

const int mod = 998244353;
vector<int> fact;

int power(int x, int y) {
    int ans = 1;
    while (y) {
        if (y & 1) ans = ans * x % mod;
        x = x % mod * x % mod, y >>= 1;
    }
    return ans;
}

int calc(int k, vector<int> a) {
    if (k == 0) return 1;
    int mid = 1ll << (k - 1);
    int cnt = 0, p = 0;

    vector<int> b(1, 0);
    for (int i = 1; i < a.size(); i += 2) {
        if (a[i] > a[i + 1])swap(a[i], a[i + 1]);
        if (a[i] == -1 && a[i + 1] == -1) cnt++, p++, b.push_back(-1);
        else if (a[i] != -1 && a[i + 1] == -1) {
            if (a[i] > mid) return 0;
            b.push_back(a[i]), cnt++;
        } else if (a[i] == -1 && a[i + 1] != -1) {
            if (a[i + 1] <= mid) b.push_back(a[i + 1]), cnt++;
            else b.push_back(-1);
        } else {
            if (a[i] > mid || a[i + 1] <= mid) return 0;
            b.push_back(a[i]);
        }
    }
    return fact[cnt] * power(2, p) % mod * calc(k - 1, b) % mod;
}

int32_t main() {
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    int k, n;
    cin >> k, n = 1 << k;
    fact = vector<int>(n + 1);
    fact[0] = 1;
    for (int i = 1; i <= n; i++) fact[i] = fact[i - 1] * i % mod;
    vector<int> a(n + 1);
    for (int i = 1; i <= n; i++) cin >> a[i];
    cout << calc(k, a);
    return 0;
}

F. Editorial for Two

二分答案。枚举出时间后,通过优先队列可以计算出规定时间内前缀可以解决的数量和后缀可以解决的数量。然后后就可以求出最多可以解决的数量。

#include <bits/stdc++.h>

using namespace std;

#define int long long

int read() {
    int x = 0, f = 1, ch = getchar();
    while ((ch < '0' || ch > '9') && ch != '-') ch = getchar();
    if (ch == '-') f = -1, ch = getchar();
    while (ch >= '0' && ch <= '9') x = (x << 3) + (x << 1) + ch - '0', ch = getchar();
    return x * f;
}

void solve() {
    int n = read(), k = read();
    vector<int> a(n);
    for (auto &i: a) i = read();

    auto check = [n, a, k](int x) {
        vector<int> b(n);
        priority_queue<int> q;
        int sum = 0;
        for (int i = 0; i < n; i++) {
            sum += a[i], q.push(a[i]);
            while( sum > x ) sum -= q.top() , q.pop();
            b[i] = q.size();
            if( b[i] >= k ) return true;
        }
        sum = 0 , q = priority_queue<int>();
        for( int i = n-1 ; i >= 0 ; i -- ){
            sum += a[i] , q.push(a[i]);
            while( sum > x ) sum -= q.top() , q.pop();
            if( i > 0 && q.size() + b[i-1] >= k) return true;
            else if( i == 0 && q.size() >= k ) return true;
        }
        return false;
    };

    int l = 0 , r = 1e18 , mid , res;
    while( l <= r ){
        mid = ( l + r ) >> 1;
        if( check(mid) ) res = mid , r = mid - 1;
        else l = mid + 1;
    }
    cout << res << "\n";
    return;
}

int32_t main() {
    for (int t = read(); t; t--) solve();
    return 0;
}

标签:Educational,Rated,return,int,Codeforces,long,else,++,cnt
From: https://www.cnblogs.com/PHarr/p/17444581.html

相关文章

  • Codeforces Round 875 (Div. 2) A-D
    A.TwinPermutations题意:给出一个由[1,2,...,n]组成的数组a,构造另一个由[1,2,...,n]组成的数组b,使得a[1]+b[1]<=a[2]+b[2]<=...<=a[n]+b[n]Solution可以想到只要让他们全为n+1就行了,这样是一定有解的voidsolve(){ intn;cin>>n; for(inti=1;i<=n;i++) { cin>>a[i]; ......
  • Codeforces Round 875 (Div
    CodeforcesRound875(Div.2)C-D题解CProblem-C-Codeforces我们发现题述所形成的父亲节点一定比子节点先画出,并且如果子节点顺序在父节点后面,则父,子节点为同一个周期加入。反之,则子节点的周期为父节点+1。所以做法考虑树上dp,维护第i个节点加入树的周期。转移方程如下:\[......
  • Codeforces Round 875 (Div. 2)
    Preface难得现场打一次,这天下午打了三个半小时的校内赛,然后八点打了两小时ARC,最后再接上两个半小时的CF真是爽歪歪不过有一说一其实很多时候都在坐牢,这场CF也差不多,一个小时写完ABCD然后开始坐牢,其实E基本想出来了但是没想到用随机赋值的方法来实现不过由于这场手很稳因此排名......
  • Codeforces Round 874 (Div. 3)
    A.MusicalPuzzle#include<bits/stdc++.h>usingnamespacestd;voidsolve(){intn;strings;cin>>n>>s;set<string>cnt;for(inti=0;i+1<n;i++)cnt.insert(s.substr(i,2));......
  • Codeforces Round 875 (Div. 2) A-D
    CodeforcesRound875(Div.2)A.TwinPermutationsinta[N];voidsolve(){intn=read();for(inti=1;i<=n;i++)a[i]=read();for(inti=1;i<=n;i++)cout<<n+1-a[i]<<'';cout<<'\n';//puts(ans&g......
  • CodeForces 1830C Hyperregular Bracket Strings
    洛谷传送门CF传送门每一步思路都非常自然的题。考虑先从一些简单的case入手。1.\(k=0\)设\(g_i\)为长度为\(i\)的合法括号串数。显然\(\foralli\nmid2,g_i=0\)。对于偶数的\(i\),这是一个经典问题,\(g_i\)就是第\(\frac{i}{2}\)项卡特兰数,因此\(g_i=\bi......
  • Codeforces Round #875 (Div. 2)
    CodeforcesRound#875(Div.2)bilibili:CodeforcesRound#875(Div.2)实况|完成度[4.01/6]A#include<bits/stdc++.h>usingll=longlong;usinguint=unsigned;usingnamespacestd;intTestCase;signedmain(){ for(scanf("%d",&......
  • Codeforces Round 875 (Div. 2) A~D
    CodeforcesRound875(Div.2)A~DA.TwinPermutations构造\(a[i]+b[i]=n+1\)voidwork(){ intn; cin>>n; rep(i,1,n){ intx; cin>>x; cout<<n-x+1<<""; } cout<<endl;}B.Arraymerging......
  • Educational Codeforces Round 149 (Rated for Div. 2)(A~F)
    A.GrasshopperonaLine题意:给出n,k,从0开始,每次可以加一个数,最快到达n需要,输出首先跳几次,然后每次跳多少,限制只有一个跳的长度不能整除k。分析:n%k,有余直接跳,没余数,先跳一个,再跳剩余的长度。代码:#include<cstring>#include<iostream>#include<algorithm>usingnamespac......
  • Codeforces 1444E - Finding the Vertex
    非常神秘的一道题,当之无愧的*3500。首先考虑转化题意。考虑一种决策树,由于我们每次问一条边之后,相当于会根据信息删掉两个连通块中的一个,因此一种决策树实际上对应了原树的一棵边分树。而为了让最坏情况下的询问次数最少,我们目标实际上是最小化边分树的深度。考虑借鉴P5912JA......