A - Spoiler
字符串
S
S
S由
S
1
∣
S
2
∣
S
3
S_1|S_2|S_3
S1∣S2∣S3组成,其中每一部分
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;
}