ABC 344

A - Spoiler

字符串 S S S S 1 ∣ S 2 ∣ S 3 S_1|S_2|S_3 S1S2S3组成,其中每一部分 S i S_i Si都是小写字母串
S 1 S 3 S_1S_3 S1S3


python split最快

# -*- 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()
    a, b, c = s.split('|')
    print(a + c)


if __name__ == "__main__":
    main()

B - Delimiter

将数组 A A A倒序输出


#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 a[101];
int n;

int main(){
    //freopen("in.txt", "r", stdin);
    int t;
    while (cin >> t) {
        a[n ++] = t;
    }
    for (int i = n - 1; i >= 0; --i) cout << a[i] << endl;
    return 0;
}

C - A+B+C

A B C ABC ABC都是大小为100以内的数组,给出 q ( ≤ 200000 ) q(\leq200000) q(200000)个查询 x x x,求是否满足
a i + b k + c j = x a_i+b_k+c_j=x ai+bk+cj=x


暴力求解

#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, l;
int a[101], b[101], c[101];

int main(){
    //freopen("in.txt", "r", stdin);
    cin >> n;
    for (int i = 1; i <= n; ++i) cin >> a[i];
    cin >> m;
    for (int i = 1; i <= m; ++i) cin >> b[i];
    cin >> l;
    for (int i = 1; i <= l; ++i) cin >> c[i];
    unordered_map<int, bool> s;
    for (int i = 1; i <= n; ++i) {
        for (int j = 1; j <= m; ++j) {
            for (int k = 1; k <= l; ++k) {
                int x = a[i] + b[j] + c[k];
                s[x] = 1;
            }
        }
    }
    int q;
    cin >> q;
    while (q--) {
        int x;
        cin >> x;
        int ok = s.count(x);
        
        if (ok) printf("Yes\n");
        else printf("No\n");
    }
    
    return 0;
}

D - String Bags

给出一个字符串 S S S
N N N个string数组,依次拼接,每次只能从数组里面选取一个字符串拼起来
求是否能拼成 S S S


#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;

string T;
int n;
int nt;
int a[101];
vector<string> vs[101];
int f[101][101];


struct Node {
    int s, i;
    bool operator <(Node r) const {
        return s > r.s;
    }
};


int main(){
    //freopen("in.txt", "r", stdin);
    cin >> T;
    nt = T.length();
    cin >> n;
    T += "#################";
    for (int i = 1; i <= n; ++i) {
        cin >> a[i];
        for (int j = 0; j < a[i]; ++j) {
            string temp;
            cin >> temp;
            vs[i].push_back(temp);
        }
    }
    memset(f, 0x7f, sizeof(f));
    f[0][0] = 0;
    for (int i = 1; i <= n; ++i) {
        for (string temp : vs[i]) {
            int l = temp.length();
            for (int k = 0; k <= nt; ++k) {
                f[i][k] = min(f[i - 1][k], f[i][k]);
                if (k + l <= nt && T.substr(k, l) == temp) {
                    f[i][k + l] = min(f[i][k + l], f[i - 1][k] + 1);
                }
            }
        }
    }
    int ans = f[n][nt];
    if (ans > 1e8) ans = -1;
    printf("%d\n", ans);
    return 0;
}

E - Insert or Erase

一个无重复的数组 A A A中进行如下操作:
对某个元素 x x x后面加入一个元素 y y y
删除某个元素 x x x
保证操作中无重复元素
求数组最后的所有元素


写一个链表

#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[200020];
unordered_map<int, int> pre, suf;
int q;


int main(){
    //freopen("in.txt", "r", stdin);
    cin >> n;
    a[0] = -1, a[n + 1] = -2;
    for (int i = 1; i <= n; ++i) cin >> a[i];
    for (int i = 1; i <= n; ++i) {
        pre[a[i]] = a[i - 1], suf[a[i]] = a[i + 1];
    }
    suf[-1] = a[1], pre[-2] = a[n];
    cin >> q;
    while (q--) {
        int o;
        cin >> o;
        if (o == 1) {
            int x, y;
            cin >> x >> y;
            int  r = suf[x];
            pre[y] = x, suf[x] = y;
            pre[r] = y, suf[y] = r;
        }
        else {
            int x;
            cin >> x;
            int l = pre[x], r = suf[x];
            pre[r] = l, suf[l] = r;
        }
    }
    int u = -1;
    while (u != -2) {
        if (u != -1) printf("%d ", u);
        u = suf[u];
    }
    return 0;
}

F - Earn to Advance

在一个 N × N N\times N N×N格子里面只能往下走或往右走,其中往下走或者往右走都需要花费一个step,并花费一定的能量 D o w n i , j Down_{i,j} Downi,j R i g h t i , j Right_{i,j} Righti,j,当能量不够时不能行走。停留在原地可以获得能量 A i , j A_{i,j} Ai,j,但要花费一个step。求从 ( 1 , 1 ) (1,1) (1,1)走到 ( n , n ) (n,n) (n,n)最少需要几个step。


很好的题。参考这篇

#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;
ll a[82][82];
ll rc[82][82], dc[82][82];
ll f[82][82][82][82];      // min cost
pll g[82][82];


int main(){
    //freopen("in.txt", "r", stdin);
    cin >> n;
    for (int i = 1; i <= n; ++i) {
        for (int j = 1; j <= n; ++j) {
            cin >> a[i][j];
        }
    }
    for (int i = 1; i <= n; ++i) {
        for (int j = 1; j < n; ++j) {
            cin >> rc[i][j];
        }
    }
    for (int i = 1; i < n; ++i) {
        for (int j = 1; j <= n; ++j) {
            cin >> dc[i][j];
        }
    }
    memset(f, 0x7f, sizeof(f));
    for (int bi = 1; bi <= n; ++bi) {
        for (int bj = 1; bj <= n; ++bj) {
            f[bi][bj][bi][bj] = 0;
            for (int ei = bi; ei <= n; ++ei) {
                for (int ej = bj; ej <= n; ++ej) {
                    ll& res = f[bi][bj][ei][ej];
                    res = min(res, f[bi][bj][ei][ej - 1] + rc[ei][ej - 1]);
                    res = min(res, f[bi][bj][ei - 1][ej] + dc[ei - 1][ej]);
                }
            }
        }
    }
    memset(g, 0x7f, sizeof(g));
    g[1][1] = { 0, 0 };
    
    for (int i = 1; i <= n; ++i) {
        for (int j = 1; j <= n; ++j) {
            for (int r = 1; r <= i; ++r) {
                for (int c = 1; c <= j; ++c) {
                    if (i == r && j == c) continue;
                    if ((a[i][j] > a[r][c] || (i == n && j == n))) {
                        auto [step, e] = g[r][c];
                        ll cost = f[r][c][i][j];
                        ll nstep, ne;
                        if (e >= cost) {
                            nstep = step + (i - r + j - c);
                            ne = e - cost;
                        }
                        else {
                            ll t = (cost - e) / a[r][c];
                            if ((cost - e) % a[r][c]) t++;
                            nstep = step + t + (i - r + j - c);
                            ne = e + t * a[r][c] - cost;
                        }
                        auto [cur_step, cur_e] = g[i][j];
                        if (nstep < cur_step || (nstep == cur_step && ne > cur_e)) {
                            g[i][j] = { nstep, ne };
                        }
                    }
                }
            }
        }
    }
    printf("%lld\n", g[n][n].first);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值