Loading

Codeforces Round #797 (Div. 3) A - F

传送门

现在还在 hack 期间,要是被 hack 了就再更新代码

G 还挺感兴趣的,找时间看看题

对 3 取模的三种情况进行构造

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <string>
#include <queue>
#include <functional>
#include <map>
#include <set>
#include <cmath>
#include <cstring>
#include <deque>
#include <stack>
using namespace std;
typedef long long ll;
#define pii pair<int, int>
const ll maxn = 2e5 + 10;
const ll inf = 1e17 + 10;
int num[10];

int main()
{
    int t;
    cin >> t;
    while(t--)
    {
        int n;
        cin >> n;
        num[0] = num[1] = num[2] = n / 3;
        num[1]++;
        num[2]--;
        n = n % 3;
        if(n >= 1)
            num[1]++;
        if(n >= 2)
            num[0]++;
        for(int i=0; i<3; i++) cout << num[i] << " ";
        cout << endl;
    
    }

    return 0;
}

B - Array Decrements

\(b_i\) 是 0 和不是 0 的情况分开讨论,不是 0 的要求一致,是 0 的情况,要求都不超过不是 0 的 \(a_i\) 的减少次数

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <string>
#include <queue>
#include <functional>
#include <map>
#include <set>
#include <cmath>
#include <cstring>
#include <deque>
#include <stack>
using namespace std;
typedef long long ll;
#define pii pair<int, int>
const ll maxn = 2e5 + 10;
const ll inf = 1e17 + 10;
int a[maxn], b[maxn];

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int t;
    cin >> t;
    while(t--)
    {
        int n;
        cin >> n;
        for(int i=0; i<n; i++) cin >> a[i];
        for(int i=0; i<n; i++) cin >> b[i];
        int f = 1, way = -1;
        int x = -1;
        for(int i=0; i<n; i++)
        {
            if(b[i] > a[i]) f = 0;
            if(b[i] == 0) {x = max(x, a[i] - b[i]); continue;}
            if(way == -1) way = a[i] - b[i];
            else
            {
                if(a[i] - b[i] != way) f = 0;
            }
        }
        if(f && x != -1 && way != -1 && x > way)
            f = 0;
        if(f) cout << "yes" << endl;
        else cout << "no" << endl;
    
    }

    return 0;
}

C - Restoring the Duration of Tasks

区间合并处理,开场就有序了,所以不用排序

只要记录更新当前时间即可

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <string>
#include <queue>
#include <functional>
#include <map>
#include <set>
#include <cmath>
#include <cstring>
#include <deque>
#include <stack>
using namespace std;
typedef long long ll;
#define pii pair<int, int>
const ll maxn = 2e5 + 10;
const ll inf = 1e17 + 10;
pii seg[maxn];

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int t;
    cin >> t;
    while(t--)
    {
        int n;
        cin >> n;
        for(int i=0; i<n; i++)
            cin >> seg[i].first;
        for(int i=0; i<n; i++)
            cin >> seg[i].second;
        int now = 0;
        for(int i=0; i<n; i++)
        {
            now = max(now, seg[i].first);
            int ans = max(0, seg[i].second - now);
            now = max(now, seg[i].second);
            cout << ans << " ";
        }
        cout << endl;
    }

    return 0;
}

D - Black and White Stripe

尺取

k 就是长度,直接判断每一个长度 为 k 的子串有多少个 W 出现即可,然后取每个区间的最小值

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <string>
#include <queue>
#include <functional>
#include <map>
#include <set>
#include <cmath>
#include <cstring>
#include <deque>
#include <stack>
using namespace std;
typedef long long ll;
#define pii pair<int, int>
const ll maxn = 2e5 + 10;
const ll inf = 1e17 + 10;
pii seg[maxn];

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int t;
    cin >> t;
    while(t--)
    {
        int n, k;
        string s;
        cin >> n >> k >> s;
        int l = 0, r = 0;
        int ans = s.length();
        int now = 0;
        while(1)
        {
            while(r < s.length() && r - l < k)
                now += s[r++] == 'W';
            if(r - l != k) break;
            ans = now < ans ? now : ans;
            now -= s[l++] == 'W';
        }
        cout << ans << endl;
    }

    return 0;
}

E - Small d and k

显然按照对 k 的同余系分类,按照一下策略进行:

选择两个数,在满足余数之和不小于 k 的前提下,尽量使最大的和最小的凑在一起

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <string>
#include <queue>
#include <functional>
#include <map>
#include <set>
#include <cmath>
#include <cstring>
#include <deque>
#include <stack>
using namespace std;
typedef long long ll;
#define pii pair<int, int>
const ll maxn = 2e5 + 10;
const ll inf = 1e17 + 10;
ll num[maxn], vis[maxn];
ll n, k;

bool cmp(const ll& a, const ll& b)
{
    return a % k < b % k;
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int t;
    cin >> t;
    while(t--)
    {
        cin >> n >> k;
        for(int i=0; i<n; i++) {cin >> num[i]; vis[i] = 0;}
        sort(num, num + n, cmp);
        int l = 0, r = n - 1;
        ll ans = 0;
        while(l < r)
        {
            while(l < r && num[l] % k + num[r] % k < k) l++;
            if(l >= r) break;
            vis[l] = vis[r] = 1;
            ans += (num[l] + num[r]) / k;
            l++;
            r--;
        }
        int pre = -1;
        for(int i=0; i<n; i++)
        {
            if(vis[i]) continue;
            if(pre == -1) pre = num[i];
            else
            {
                ans += (pre + num[i]) / k;
                pre = -1;
            }
        }
        cout << ans << endl;
    }

    return 0;
}

F - Shifting String

对排列进行 dfs 的话,显然会形成一个环,就考虑这个环能否回到最初

因此答案就是求每个环的最小循环节的最小公倍数

求循环节的话,考虑到串并不长,可暴力,可 kmp

这题一直卡在求错了若干个数的最小公倍数上,麻了,一直以为思路错了,想不到是自己蠢

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <string>
#include <queue>
#include <functional>
#include <map>
#include <set>
#include <cmath>
#include <cstring>
#include <deque>
#include <stack>
using namespace std;
typedef long long ll;
#define pii pair<int, int>
const ll maxn = 2e5 + 10;
const ll inf = 1e17 + 10;
int vis[maxn], num[maxn], nex[maxn];
string ss, s;

ll gcd(ll a, ll b)
{
    return b == 0 ? a : gcd(b, a % b);
}

void getnext()
{
    int len = ss.length(), j = -1, i = 0;
    nex[0] = -1;
    while(i < len)
    {
        if(j == -1 || ss[j] == ss[i])
            nex[++i] = ++j;
        else
            j = nex[j];
    }
}

void dfs(int now, ll& tot)
{
    if(vis[now]) return;
    tot++;
    vis[now] = 1;
    ss += s[now];
    dfs(num[now], tot);
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int t;
    cin >> t;
    while(t--)
    {
        int n;
        cin >> n >> s;
        s = "a" + s;
        for(int i=1; i<=n; i++) {cin >> num[i]; vis[i] = 0;}
        vector<ll>v;
        for(int i=1; i<=n; i++)
        {
            ll ans = 0;
            if(vis[i]) continue;
            ss = "";
            dfs(i, ans);
            getnext();
            ll x = ss.length() - nex[ss.length()];
            if(x && ss.length() % x == 0) ans = x;
            v.push_back(ans);
        }
        ll ans = 1;
        for(int i=0; i<v.size(); i++)
        {
            ll x = gcd(ans, v[i]);
            ans = ans / x * v[i];
        }
        cout << ans << endl;
    }

    return 0;
}
posted @ 2022-06-08 09:00  dgsvygd  阅读(42)  评论(0编辑  收藏  举报