Codeforces Round #820 (Div. 3)

前置废话

今天早上没有比赛安排,所以在 \(Codeforces\) 上VP了一个Div3,到\(E\)切不动了,就来写写收获。


Codeforces Round #820 (Div. 3)

A B 过于水,就不说了
只有 B 数组开小没有 1A

C. Jumping on Tiles

考虑到有一个必须的花费是直接从第一个到最后一个,那么可以将字符数组排个序,在第一个字符与最后一个字符之间的都可以跳到,那么直接按循序跳就行,这也就保证了步数最小。

Code moo~~
#include <iostream>
#include <cmath>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <map>
#include <vector>
using namespace std;
#define int long long
#define re register int
#define pc_ putchar(' ')
#define pc_n putchar('\n')
#define Bessie signed
inline int read() {
    int A = 0, FL = 1;
    char CH = getchar();
    while(CH < '0' || CH > '9') FL = CH == '-' ? -1 : 1, CH = getchar();
    while(CH >= '0' && CH <= '9') A = (A << 3) + (A << 1) + (CH ^ '0'), CH = getchar();
    return A * FL;
}
inline void ot(int x) {
    if(x < 0) putchar('-'), x = -x;
    if(x >= 10) ot(x / 10); putchar(x % 10 | '0');
}
const int CTR = 2e5 + 7;
int T;
int n;
char b[30], a[CTR];
int dp[CTR];
map<char, int> mp;
bool vis[30];
bool cmp(char x, char y) {
    return mp[x] < mp[y];
}
vector<int>G[CTR];
char be, ed;
int l, r, ans;
Bessie main() {
    for(re i = 1; i <= 26; ++i) {
        b[i] = 'a' + i - 1;
        // ot(i), pc_, cout << b[i] << endl;
        mp[b[i]] = i;
    }
    T = read();
    while(T--) {
        scanf("%s", a + 1);
        n = strlen(a + 1);
        be = a[1], ed = a[n];
        ans = l = r = 0;
        for(re i = 1; i <= 26; ++i) G[i].clear(), vis[i] = 0; 
        for(re i = 1; i <= n; ++i) {
            G[mp[a[i]]].push_back(i);
        }
        sort(a + 1, a + n + 1, cmp);
        if(be <= ed) {
            for(re i = 1; i <= n; ++i) { if(a[i] == be && l == 0) { l = i; break; } }
            for(re i = n; i >= 1; --i) { if(a[i] == ed && r == 0) { r = i; break; } }
            for(re i = l; i <= r; ++i) {
                if(vis[mp[a[i]]]) continue;
                vis[mp[a[i]]] = 1;
                if(a[i] != a[i - 1] && i != l) ans += mp[a[i]] - mp[a[i - 1]];
            }
            ot(ans),pc_,ot(r - l + 1),pc_n;
            for(re i = 1; i <= 26; ++i) vis[i] = 0;
            for(re i = l; i <= r; ++i) {
                if(vis[mp[a[i]]]) continue;
                vis[mp[a[i]]] = 1;
                if(a[i] != a[i - 1] && i != l) ans += mp[a[i]] - mp[a[i - 1]];
                for(auto it : G[mp[a[i]]]) {
                    ot(it),pc_;
                }
            }
            pc_n;
        }
        if(be > ed) {
            for(re i = 1; i <= n; ++i) { if(a[i] == ed && r == 0) { r = i; break; } }
            for(re i = n; i >= 1; --i) { if(a[i] == be && l == 0) { l = i; break; } }
            for(re i = l; i >= r; --i) {
                if(vis[mp[a[i]]]) continue;
                vis[mp[a[i]]] = 1;
                if(a[i] != a[i + 1] && i != l) ans += mp[a[i + 1]] - mp[a[i]];
            }
            ot(ans),pc_,ot(l - r + 1),pc_n;
            for(re i = 1; i <= 26; ++i) vis[i] = 0;
            for(re i = l; i >= r; --i) {
                if(vis[mp[a[i]]]) continue;
                vis[mp[a[i]]] = 1;
                for(auto it : G[mp[a[i]]]) {
                    ot(it),pc_;
                }
            }
            pc_n;
        }
    }
    return 0;
}

D. Friends and the Restaurant

这题还是卡我挺长时间的。首先转化一下题意:设\(a_i = y_i - x_i\),选出的集合为\(S\)

那么每次就是让\(\sum_{i \in S} a_i \ge 0\)。题目让选的次数尽量多,可以贪心的每次只选两个。

所以将\(a_i\)排好序,双指针扫一遍就可以了。

我原来还想用STL搞,后来重构时才想到这个解法。

Code moo~~
#include <iostream>
#include <cmath>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <map>
#include <vector>
#include <set>
using namespace std;
#define int long long
#define re register int
#define pc_ putchar(' ')
#define pc_n putchar('\n')
#define Bessie signed
inline int read() {
    int A = 0, FL = 1;
    char CH = getchar();
    while(CH < '0' || CH > '9') FL = CH == '-' ? -1 : 1, CH = getchar();
    while(CH >= '0' && CH <= '9') A = (A << 3) + (A << 1) + (CH ^ '0'), CH = getchar();
    return A * FL;
}
inline void ot(int x) {
    if(x < 0) putchar('-'), x = -x;
    if(x >= 10) ot(x / 10); putchar(x % 10 | '0');
}
const int CTR = 2e5 + 7, INF = 0x7f7f7f7f;
int T;
int n;
int a[CTR], ans;
bool cmp(int x, int y) { return x > y; }
int l, r;
Bessie main() {
    T = read();
    while(T--) {
        n = read();
        ans = 0;
        l = 1, r = n;
        for(re i = 1; i <= n; ++i) a[i] = read();
        for(re i = 1, y; i <= n; ++i) {
            y = read();
            a[i] = y - a[i];
        }
        sort(a + 1, a + n + 1, cmp);
        // for(re i = 1; i <= n; ++i) ot(a[i]),pc_;
        // pc_n;
        while(l <= r) {
            while(l < r && a[l] + a[r] < 0) r--;
            if(l == r) break;
            ans++;
            // ot(l),pc_,ot(r),pc_n;
            l++;
            r--;
        }
        ot(ans),pc_n;
    }
    return 0;
}

后置废话

下午还想再来一场。

posted @ 2022-09-23 10:50  Creator_157  阅读(46)  评论(1编辑  收藏  举报