Loading

Codeforces Round 966 (Div. 3)

传送门

赛时A-F

A.

模拟

B.

模拟,判断其两边是否有乘客,若符合给该位置打上标记。

C.

用 map 给字母和数字建立起映射。

哦哦,map被卡了,用数组好了。

D.

找到最左的 L 和最右的 R,再双指针往里缩,前缀和优化即可。

#include<bits/stdc++.h>
#define int long long
using namespace std;

const int N = 1e6 + 7;
int a[N];
void solve() {
    
    int n;
    cin >> n;
    for(int i = 1; i <= n; i ++) cin >> a[i];
    for(int i = 1; i <= n; i ++) a[i] += a[i - 1];
    string s;
    cin >> s;
    s = ' ' + s;
    int l = 1, r = n;
    int ans = 0;
    while(1) {
        while(s[l] != 'L' && l <= n) l ++;
        while(s[r] != 'R' && r >= 1) r --;
        
        if(l <= r) ans += (a[r] - a[l - 1]);
        else break;
        l ++, r --;
    }
    cout << ans << endl;
}
signed main() {
    int T;
    cin >> T;
    while(T --) solve();
}

E.

记录每个位置会被拍多少次,可以用二维前缀和,然后贪心地把高的猩猩往次数多的地方放。

#include<bits/stdc++.h>
#define int long long
using namespace std;

const int N = 1e6 + 7;
int a[N];
int pp[N];
bool cmp(int x, int y) {return x > y;};
void solve() {
    int n, m, k;
    cin >> n >> m >> k;
    int w;
    cin >> w;
    int p[n + 10][m + 10] = {};
    for(int i = 1; i <= n * m; i ++) pp[i] = 0;
    for(int i = 1; i <= w; i ++) cin >> a[i];
    for (int i = 1; i <= n; i ++){
        for(int j = 1; j <= m; j ++){
            if (i + k - 1 <= n && j + k - 1 <= m) {
                p[i][j]++;
                p[i][j + k]--;
                p[i + k][j]--;
                p[i + k][j + k]++;
            }
        }
    }
    
    for(int i = 1; i <= n; i ++) {
        for(int j = 1; j <= m; j ++) {
            p[i][j] += p[i - 1][j] + p[i][j - 1] - p[i - 1][j - 1];
            pp[(i - 1) * m + j] = p[i][j];
        }
    }
        
            

    sort(pp + 1, pp + n * m + 1, cmp);
    sort(a + 1, a + w + 1, cmp);
    int ans = 0;
    for(int i = 1; i <= w; i ++) {
        ans += pp[i] * a[i];
    }
    cout << ans << endl;
}
signed main() {
    ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    int T;
    cin >> T;
    while(T --) solve();
}

F.

观察到一定是对一个矩形统一操作,然后再到下一矩形。可以对于每个矩形处理出得 \(i\) 分需要多少步, \(f_i\) 表示达到 \(i\) 分最少需要几步,由于数据很小,随便转移即可。


#include<bits/stdc++.h>
#define int long long
using namespace std;

const int N = 1e6 + 7;
int f[N];
void solve() {
    int n, k;
    cin >> n >> k;
    for(int i = 1; i <= k; i ++) f[i] = 1e9;
    f[0] = 0;
    while(n --) {
        int a, b;
        cin >> a >> b;
        int aa = a, bb = b;
        int p[a + b + 2] = {};
        int cnt = 0;
        for(int i = 1; i <= a + b; i ++) {
            if(aa <= bb) {
                p[++ cnt] = aa;
                bb --;
            }
            else {
                p[++ cnt] = bb;
                aa --;
            }
        }
        for(int i = 1; i <= cnt; i ++) p[i] += p[i - 1];

        for(int i = k; i >= 1; i --) {
            for(int j = min(a + b, i); j >= 1; j --) {
                f[i] = min(f[i], f[i - j] + p[j]);
            }
        }

    }
    if(f[k] == 1e9) cout << -1 << endl;
    else cout << f[k] << endl;
}
signed main() {
    ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    int T;
    cin >> T;
    while(T --) solve();
}
posted @ 2024-08-15 02:52  你说得太对辣  阅读(93)  评论(0)    收藏  举报