AtCoder Beginner Contest 281 补题报告

传送门AtCoder Beginner Contest 281

 

∗ * B - Sandwich Number

Tutorial

一道纯纯的大水题,判断字符串第一个和最后一个是大写字母,中间6位是数字且不含前导0即可
字符串长度有且仅有8位!8位!!啊啊啊啊啊

Solution

#include <bits/stdc++.h>
#define int long long
#define vi vector<int>
#define pii pair<int, int>
#define inf 0x3f3f3f3f
const int N = 2e5 + 7, mod = 998244353;
using namespace std;

bool check(char ch) {
    return ch >= 'A' && ch <= 'Z';
}

bool checkk(char ch) {
    return ch >= '0' && ch <= '9';
}

signed main() {
    string s;
    cin >> s;
    bool f = 1;
    if (!check(s.front()) || !check(s.back())) f = 0;
    if (s.size() != 8) f = 0;
    for (int i = 1; i < 7; i++)
        if (!checkk(s[i])) f = 0;
    if (s[1] == '0') f = 0;
    cout << (f ? "Yes" : "No");
}

$nbsp;

∗ * D - Max Multiple

Tutorial

dp
f ( i , j , k ) f(i,j,k) f(i,j,k) 表示从 a 1 , ⋯   , a i a_1,\cdots,a_i a1,,ai 中选出 j j j 个元素,且这 j j j 个元素的和模 D D D k k k(如果做不到则 k = − 1 k=-1 k=1
那么对于 a i a_i ai 我们有选或者不选两种状态,状态转移方程如下:

//不选上a[i]
f[i+1][j][k] = max(f[i+1][j][k], f[i][j][k]);
//选上a[i]
f[i+1][j+1][(k+a[i])%D] = max(f[i+1][j+1][(k+a[i])%D], f[i][j][k]+a[i]);

最后我们所求的答案即为 f ( N , K , 0 ) f(N,K,0) f(N,K,0)

Solution

#include <bits/stdc++.h>
#define int long long
#define vi vector<int>
#define pii pair<int, int>
#define inf 0x3f3f3f3f
const int N = 2e5 + 7, mod = 998244353;
using namespace std;

int a[N];
int f[107][107][107];

signed main() {
    int n, k, d;
    cin >> n >> k >> d;
    for (int i = 0; i < n; i++) cin >> a[i];
    memset(f, -1, sizeof f);
    f[0][0][0] = 0;
    for (int i = 0; i < n; i++)
        for (int j = 0; j <= k; j++)
            for (int l = 0; l < d; l++) {
                if (f[i][j][l] == -1) continue;
                f[i + 1][j][l] = max(f[i + 1][j][l], f[i][j][l]);
                if (j != k) f[i + 1][j + 1][(l + a[i]) % d] = max(f[i + 1][j + 1][(l + a[i]) % d], f[i][j][l] + a[i]);
            }
    cout << f[n][k][0];
}

 

E - Least Elements

Tutorial

找出 a i , ⋯   , a i + m a_i,\cdots,a_{i+m} ai,,ai+m 中前 k k k 小的数的和
可以用两个 m u l t i s e t multiset multiset 进行维护, l l l 中存放当前 m m m 个数中前 k k k 小的数, r r r 中存放当前 m m m 个数中剩下的数
由于 m u l t i s e t multiset multiset 是有序的,动态维护 l l l r r r ,那么每次的答案即为 l l l 中所有数之和

Solution

#include <bits/stdc++.h>
#define int long long
#define vi vector<int>
#define pii pair<int, int>
#define inf 0x3f3f3f3f
const int N = 2e5 + 7, mod = 998244353;
using namespace std;

int a[N];
multiset<int> l, r;

int popfront(multiset<int> &s) {
    auto it = s.begin();
    int val = *it;
    s.erase(it);
    return val;
}

int popback(multiset<int> &s) {
    auto it = prev(s.end());
    int val = *it;
    s.erase(it);
    return val;
}

signed main() {
    int n, m, k, ans = 0;
    cin >> n >> m >> k;
    for (int i = 1; i <= n; i++) cin >> a[i];
    for (int i = 1; i <= m; i++) {
        l.insert(a[i]);
        ans += a[i];
        if (l.size() > k) {
            int val = popback(l);
            r.insert(val);
            ans -= val;
        }
    }
    for (int i = 1; i <= n - m + 1; i++) {
        cout << ans << ' ';
        if (k == m) ans += a[i + m] - a[i];
        else {
            l.insert(a[i + m]);
            ans += a[i + m];
            int val = popback(l);
            r.insert(val);
            ans -= val;
            if (r.find(a[i]) != r.end()) r.erase(r.find(a[i]));
            else {
                l.erase(l.find(a[i]));
                ans -= a[i];
                int val = popfront(r);
                l.insert(val);
                ans += val;
            }
        }
    }
}

 

F、G、Ex待补

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值