Atcoder ABC 379

A - Cyclic

三位正整数abcabcabc,输出bcabcabcacabcabcab

# -*- coding: utf-8 -*-
# @time     : 2023/6/2 13:30
# @file     : atcoder.py
# @software : PyCharm

import bisect
import copy
import sys
from itertools import permutations
from collections import defaultdict, Counter, deque
from functools import lru_cache, cmp_to_key
import heapq
import math
sys.setrecursionlimit(100010)


def main():
    items = sys.version.split()
    fp = open("in.txt") if items[0] == "3.10.6" else sys.stdin
    s = fp.readline().strip()
    s0 = s[1] + s[2] + s[0]
    s1 = s[2] + s[0] + s[1]
    print(s0, s1)


if __name__ == "__main__":
    main()

B - Strawberries

字符串ooxxx代表牙齿,其中o代表健康的牙齿。
当有连续的k颗健康牙齿时,可以吃掉一颗草莓。问最多能吃几个草莓。


记录一个cnt,用于维护连续的牙齿数

# -*- coding: utf-8 -*-
# @time     : 2023/6/2 13:30
# @file     : atcoder.py
# @software : PyCharm

import bisect
import copy
import sys
from itertools import permutations
from collections import defaultdict, Counter, deque
from functools import lru_cache, cmp_to_key
import heapq
import math
sys.setrecursionlimit(100010)


def main():
    items = sys.version.split()
    fp = open("in.txt") if items[0] == "3.10.6" else sys.stdin
    n, k = map(int, fp.readline().split())
    s = fp.readline().strip()
    ans = 0
    o = 0
    for i in range(n):
        if s[i] == 'O':
            o += 1
        else:
            ans += o // k
            o = 0
    ans += o // k
    print(ans)


if __name__ == "__main__":
    main()

C - Sowing Stones

在一列格子里面有m个位置存着石头,每个位置xix_ixi里有aia_iai个石头。石头只能往右边移动,最后需要让每个格子里有一个石头。
问1.是否可能,2.需要几步。


从右往左遍历一遍,看对于每个i是否满足ai+ai+1+...≤(n−xi+1)a_i+a_{i+1}+... \leq (n-x_i+1)ai+ai+1+...(nxi+1)
如果满足,最后将题目看做是在一个数轴上移动数字的问题。
答案是∑[1..n]−∑xi∗ai\sum[1..n]-\sum x_i*a_i[1..n]xiai

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <string>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <map>
#include <set>
#include <vector>
#include <queue>
#include <stack>
#include <unordered_map>
#include <algorithm>

using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef vector<int> vi;

int n, m;
pii a[200010];


int main(){
    //freopen("in.txt", "r", stdin);
    cin >> n >> m;
    for (int i = 1; i <= m; ++i) {
        cin >> a[i].first;
    }
    for (int i = 1; i <= m; ++i) {
        cin >> a[i].second;
    }
    sort(a + 1, a + m + 1);
    ll s = 0;
    for (int i = m; i >= 1; --i) {
        ll len = n - a[i].first + 1;
        s += a[i].second;
        if (s > len)
        {
            printf("-1\n");
            return 0;
        }
    }
    if (s != n) {
        printf("-1\n");
        return 0;
    }

    ll ans = ll(n + 1) * n / 2;
    for (int i = 1; i <= m; ++i) {
        ans -= ll(a[i].first) * a[i].second;
    }
    printf("%lld\n", ans);
}

D - Home Garden

三个操作
1.种一棵树。此时该树的高度为0.
2.浇水h,此时所有树的高度增加h。
3.收获w,此时所有>=w的树收割。


aia_iai是当前(i操作后)一共浇了多少水
那么i操作下的树当前的高度是acur−ai−1a_{cur}-a_{i-1}acurai1
维护一个栈,用于操作2下去掉那些足够高的树

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <string>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <map>
#include <set>
#include <vector>
#include <queue>
#include <stack>
#include <unordered_map>
#include <algorithm>

using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef vector<int> vi;

int q;
ll a[200020];
bool b[200020];
int idx;
queue<int> qu;


void work() {
    int op;
    cin >> op;
    if (op == 1) {
        ++idx;
        a[idx] = a[idx - 1];
        qu.push(idx);
        b[idx] = 1;
    }
    else if(op == 2){
        ++idx;
        ll t;
        cin >> t;
        a[idx] = a[idx - 1] + t;
    }
    else {
        ++idx;
        ll t;
        cin >> t;
        a[idx] = a[idx - 1];
        int cnt = 0;
        while (qu.size() && a[idx] - a[qu.front()] >= t) {
            if (b[qu.front()])
                cnt++;
            qu.pop();
        }
        printf("%d\n", cnt);
    }
}


int main(){
    //freopen("in.txt", "r", stdin);
    cin >> q;
    while (q--) {
        work();
    }
    return 0;
}

E - Sum of All Substrings

高精度加法,但是不能暴力
把一个字符串SSS代表的整数里的每个子字符串加起来,求和。


不能暴力的情况下,分不同数位上的数
手算例子:
f(379)f(379)f(379)在百位只有3
在十位有37 79 379=3+7*2
在个位有3 37 379 7 79 9 =3+7∗2+9∗3= 3+7*2+9*3=3+72+93
所以从高位到低位维护一个前缀和,高精度加上去就好了

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <string>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <map>
#include <set>
#include <vector>
#include <queue>
#include <stack>
#include <unordered_map>
#include <algorithm>

using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef vector<int> vi;

int n;
int a[400040];
string s;
ll ts;


int main(){
    //freopen("in.txt", "r", stdin);
    cin >> n;
    cin >> s;
    for (int i = 0; i < n; ++i) {
        int d = s[i] - '0';
        int t = d * (i + 1);
        ts += t;
        int j = n - 1 - i;
        ll c = 0;
        ll x = ts;
        while (true) {
            int y = a[j] + x % 10 + c;
            a[j] = y % 10;
            c = y / 10;
            if (a[j] == 0 && x == 0 && c == 0)
                break;
            j++;
            x /= 10;
        }
    }
    int m = 0;
    for (int i = 400039; i >= 0; --i) {
        if (a[i]) {
            m = i;
            break;
        }
    }
    for (int i = m; i >= 0; --i) {
        printf("%d", a[i]);
    }
    printf("\n");
    return 0;
}

F - Buildings 2

一排楼房
给出q个查询,每个查询里面有两个下标l, r
定义当xi=max⁡k=[i+1..j]xkx_i=\max_{k=[i+1..j]}x_kxi=maxk=[i+1..j]xk时楼房i能被楼房j看见
也就是楼房i和楼房j之间没有更高的楼房。
问、能被lr同时看见的楼房个数。


如果单独问i看见的楼房个数,显然是求LIS最长不下降子序列
但是算两个联合起来,如果先算r看见的LIS,然后去判l和LIS的关系,不太好做。反过来,先算l看见的LIS,再看r在LIS中的位置,我们就可以很容易做出来。

G - Count Grid 3-coloring

状态压缩dp模板题。需要优化,差点就TLE了。

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <string>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <map>
#include <set>
#include <vector>
#include <queue>
#include <stack>
#include <unordered_map>
#include <algorithm>

using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef vector<int> vi;

ll mod = 998244353;
int n, m;
int a[201][201];
int b[202][15];
ll f[202][25000];
int p[16];
vi seq;
int sz;
vi g[25000];
int dx[25000][14];


inline int get3(int x, int pos) {
    return (x % p[pos + 1]) / p[pos];
}


int main(){
    //freopen("in.txt", "r", stdin);
    cin >> n >> m;
    p[0] = 1;
    for (int i = 1; i <= 15; ++i)
        p[i] = p[i - 1] * 3;
    for (int i = 1; i <= n; ++i) {
        char c;
        for (int j = 1; j <= m; ++j) {
            cin >> c;
            if (c != '?') a[i][j] = c - '1';
            else a[i][j] = -1;
        }
    }
    if (n < m) {
        for (int i = 1; i <= n; ++i) {
            for (int j = 1; j <= m; ++j) {
                b[j][i - 1] = a[i][j];
            }
        }
        swap(n, m);
    }
    else {
        for (int i = 1; i <= n; ++i) {
            for (int j = 1; j <= m; ++j) {
                b[i][j - 1] = a[i][j];
            }
        }
    }
    // n > m
    for (int i = 0; i < p[m]; ++i) {
        bool ok = 1;
        for (int j = 0; j < m - 1; ++j) {
            if (get3(i, j) == get3(i, j + 1)) {
                ok = 0;
                break;
            }
        }
        if (ok) seq.push_back(i);
    }
    sz = seq.size();
    for (int i = 0; i < sz; ++i) {
        for (int j = 0; j < m; ++j) {
            dx[i][j] = get3(seq[i], j);
        }
    }
    for (int i = 0; i < sz; ++i) {
        for (int j = 0; j < sz; ++j) {
            bool ok = 1;
            for (int k = 0; k < m; ++k) {
                if (dx[i][k] == dx[j][k]) {
                    ok = 0;
                    break;
                }
            }
            if (ok) g[i].push_back(j);
        }
    }
    f[0][0] = 1;
    for (int i = 1; i <= n; ++i) {
        for (int j = 0; j < sz; ++j) {
            bool ok = 1;
            for (int k = 0; k < m; ++k) {
                int t = get3(seq[j], k);
                if (b[i][k] != -1 && t != b[i][k]) {
                    ok = 0;
                    break;
                }
            }
            if (!ok) continue;
            if (i == 1) f[i][j] = 1;
            else {
                for (int prej : g[j]) {
                    f[i][j] = (f[i][j] + f[i - 1][prej]) % mod;
                }
            }
        }
    }
    ll ans = 0;
    for (int j = 0; j < sz; ++j) {
        ans = (ans + f[n][j]) % mod;
    }
    printf("%lld\n", ans);
    return 0;
}
关于 AtCoder Beginner Contest 387 的信息如下: ### 关于 AtCoder Beginner Contest 387 AtCoder Beginner Contest (ABC) 是一项面向编程爱好者的定期在线竞赛活动。对于 ABC387,该赛事通常会在周末举行,并持续大约100分钟,在此期间参赛者需解决一系列算法挑战问题。 #### 比赛详情 - **举办平台**: AtCoder Online Judge System[^2] - **比赛时间长度**: 大约为1小时40分钟 - **难度级别**: 初学者友好型,适合那些刚开始接触竞争性程序设计的人群参与 - **题目数量**: 一般情况下会提供四到六道不同难度级别的题目供选手解答 #### 题目概览 虽然具体细节可能因官方发布而有所变化,但可以预期的是,这些题目将会覆盖基础的数据结构、字符串处理以及简单图论等方面的知识点。每一道题目的描述都会清晰给出输入输出格式说明及样例测试数据以便理解需求并验证解决方案的有效性。 为了获取最准确的比赛时间和确切的题目列表,请访问 [AtCoder 官方网站](https://atcoder.jp/) 并查看最新的公告板或直接导航至对应编号的具体页面来获得更新的信息。 ```python import requests from bs4 import BeautifulSoup def get_contest_info(contest_id): url = f"https://atcoder.jp/contests/{contest_id}" response = requests.get(url) if response.status_code == 200: soup = BeautifulSoup(response.text, 'html.parser') title_element = soup.find('title') problem_list_elements = soup.select('.panel.panel-default a[href^="/contests/{}/tasks"]'.format(contest_id)) contest_title = title_element.string.strip() if title_element else "Contest Title Not Found" problems = [element['href'].split('/')[-1] for element in problem_list_elements] return { "name": contest_title, "problems": problems } else: raise Exception(f"Failed to fetch data from {url}") abc_387_details = get_contest_info("abc387") print(abc_387_details) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值