ABC 338
手有点答辩,老是按错键,多吃了 \(2\) 罚时/cf
A
#include <bits/stdc++.h>
#define fi first
#define se second
#define pb push_back
#define mk make_pair
#define ll long long
#define space putchar(' ')
#define enter putchar('\n')
using namespace std;
inline int read() {
int x = 0, f = 1;
char c = getchar();
while (c < '0' || c > '9') f = c == '-' ? -1 : f, c = getchar();
while (c >= '0' && c <= '9') x = (x<<3)+(x<<1)+(c^48), c = getchar();
return x*f;
}
inline void write(int x) {
if (x < 0) x = -x, putchar('-');
if (x > 9) write(x/10);
putchar('0'+x%10);
}
bool solve() {
string s;
cin >> s;
if ('a' <= s[0] && s[0] <= 'z') return 0;
for (int i = 1; s[i]; ++i) if ('A' <= s[i] && s[i] <= 'Z') return 0;
return 1;
}
int main() {
puts(solve() ? "Yes" : "No");
return 0;
}
B
#include <bits/stdc++.h>
#define fi first
#define se second
#define pb push_back
#define mk make_pair
#define ll long long
#define space putchar(' ')
#define enter putchar('\n')
using namespace std;
inline int read() {
int x = 0, f = 1;
char c = getchar();
while (c < '0' || c > '9') f = c == '-' ? -1 : f, c = getchar();
while (c >= '0' && c <= '9') x = (x<<3)+(x<<1)+(c^48), c = getchar();
return x*f;
}
inline void write(int x) {
if (x < 0) x = -x, putchar('-');
if (x > 9) write(x/10);
putchar('0'+x%10);
}
int mx, cnt[500];
char ans;
int main() {
string s;
cin >> s;
for (int i = 0; s[i]; ++i) {
++cnt[s[i]];
if (cnt[s[i]] > mx) ans = s[i], mx = cnt[s[i]];
else if (cnt[s[i]] == mx && s[i] < ans) ans = s[i];
}
cout << ans;
return 0;
}
C
瞪的第一眼没有看出来,第二眼爆炸了,第三眼看到了 \(N\le 10\)。
枚举即可。
#include <bits/stdc++.h>
#define fi first
#define se second
#define pb push_back
#define mk make_pair
#define ll long long
#define space putchar(' ')
#define enter putchar('\n')
using namespace std;
inline int read() {
int x = 0, f = 1;
char c = getchar();
while (c < '0' || c > '9') f = c == '-' ? -1 : f, c = getchar();
while (c >= '0' && c <= '9') x = (x<<3)+(x<<1)+(c^48), c = getchar();
return x*f;
}
inline void write(int x) {
if (x < 0) x = -x, putchar('-');
if (x > 9) write(x/10);
putchar('0'+x%10);
}
const int N = 15;
int n, ans, flag = 1, a[N], b[N], q[N];
int main() {
cin >> n;
for (int i = 1; i <= n; ++i) cin >> q[i];
for (int i = 1; i <= n; ++i) cin >> a[i];
for (int i = 1; i <= n; ++i) cin >> b[i];
for (int i = 0; i <= 1e6; ++i) {
int mn = 1e9;
for (int j = 1; j <= n; ++j) {
if (i*a[j] > q[j]) {
flag = 0;
break;
}
if (b[j]) mn = min(mn, (q[j]-i*a[j])/b[j]);
}
if (!flag) break;
ans = max(ans, i+mn);
}
cout << ans;
return 0;
}
D
没做出来。
记 \(v_i\) 为拆掉 \((i,i\bmod n+1)\) 之间的桥的答案。
若当前需要从 \(x\) 走到 \(y\),可以选两种路径,假设走了其中一种,那么另一种路径上的桥都可以拆掉,所以那些桥对应的 \(v_i\) 就得加上路径长。再用差分优化,最后取最小值。
#include <bits/stdc++.h>
#define int long long
#define fi first
#define se second
#define pb push_back
#define mk make_pair
#define ll long long
#define space putchar(' ')
#define enter putchar('\n')
using namespace std;
inline int read() {
int x = 0, f = 1;
char c = getchar();
while (c < '0' || c > '9') f = c == '-' ? -1 : f, c = getchar();
while (c >= '0' && c <= '9') x = (x<<3)+(x<<1)+(c^48), c = getchar();
return x*f;
}
inline void write(int x) {
if (x < 0) x = -x, putchar('-');
if (x > 9) write(x/10);
putchar('0'+x%10);
}
const int N = 2e5+5;
int n, m, ans = 1e18, a[N], c[N];
void add(int l, int r, int k) { c[l] += k, c[r+1] -= k; }
signed main() {
cin >> n >> m;
for (int i = 1; i <= m; ++i) cin >> a[i];
for (int i = 1; i < m; ++i) {
int x = a[i], y = a[i+1];
if (x > y) swap(x, y);
int d = y-x;
add(1, x-1, d);
add(x, y-1, n-d);
add(y, n, d);
}
for (int i = 1; i <= n; ++i) c[i] += c[i-1], ans = min(ans, c[i]);
cout << ans;
return 0;
}
E
吃了两罚时/cf
先考虑把圆拉直,那么弦会形成若干个区间,显然若两个区间区间包含或没有交点,则图上这两条弦就没有相交。用栈判断即可。
#include <bits/stdc++.h>
#define fi first
#define se second
#define pb push_back
#define mk make_pair
#define ll long long
#define space putchar(' ')
#define enter putchar('\n')
using namespace std;
inline int read() {
int x = 0, f = 1;
char c = getchar();
while (c < '0' || c > '9') f = c == '-' ? -1 : f, c = getchar();
while (c >= '0' && c <= '9') x = (x<<3)+(x<<1)+(c^48), c = getchar();
return x*f;
}
inline void write(int x) {
if (x < 0) x = -x, putchar('-');
if (x > 9) write(x/10);
putchar('0'+x%10);
}
typedef pair <int, int> pii;
const int N = 4e5+5;
int n, top, stk[N];
pii v[N];
int main() {
cin >> n;
for (int i = 1; i <= n; ++i) {
int x = read(), y = read();
if (x > y) swap(x, y);
v[x] = mk(1, i);
v[y] = mk(0, i);
}
for (int i = 1; i <= n<<1; ++i) {
if (v[i].fi) stk[++top] = v[i].se;
else if (stk[top--] != v[i].se) puts("Yes"), exit(0);
}
puts("No");
return 0;
}
F
第一眼没什么头绪,后来看到了 \(n\le 20\),显然是状压。
但是状压不怎么打,所以 T 了,但是多亏了 lxj 的帮助,过了。
#include <bits/stdc++.h>
#define fi first
#define se second
#define pb push_back
#define mk make_pair
#define ll long long
#define space putchar(' ')
#define enter putchar('\n')
using namespace std;
inline int read() {
int x = 0, f = 1;
char c = getchar();
while (c < '0' || c > '9') f = c == '-' ? -1 : f, c = getchar();
while (c >= '0' && c <= '9') x = (x<<3)+(x<<1)+(c^48), c = getchar();
return x*f;
}
inline void write(int x) {
if (x < 0) x = -x, putchar('-');
if (x > 9) write(x/10);
putchar('0'+x%10);
}
const int N = 21;
int n, m, ans = 1e9, f[1<<N][N], d[N][N];
int main() {
cin >> n >> m;
memset(d, 0x3f, sizeof(d));
while (m--) {
int x = read(), y = read(), w = read();
d[x][y] = w;
}
for (int k = 1; k <= n; ++k)
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= n; ++j)
d[i][j] = min(d[i][j], d[i][k]+d[k][j]);
memset(f, 0x3f, sizeof(f));
for (int i = 1; i <= n; ++i) f[1<<i-1][i] = 0;
for (int i = 0; i < 1<<n; ++i)
for (int j = 1; j <= n; ++j) if (i>>j-1&1)
for (int k = 1; k <= n; ++k) if ((i^1<<j-1)>>k-1&1)
f[i][j] = min(f[i][j], f[i^1<<j-1][k]+d[k][j]);
for (int i = 1; i <= n; ++i) ans = min(ans, f[(1<<n)-1][i]);
if (ans != 1e9) cout << ans;
else cout << "No";
return 0;
}
G
比赛时没有看这题,因为全在想 D,后来看了看题,还是不会做。
考虑计算每个数字说对应的贡献,当没有乘号时,还比较好处理。当有乘号时,为了不重复计算贡献,所以应把贡献放在最后一个数字上,通过这样避免重复的计算,时间复杂度可以达到线性。
代码没写,调不出来。
放个官方代码:
S = input()
MOD = 998244353
p10 = [1] * (len(S) + 1)
for i in range(len(S)):
p10[i + 1] = p10[i] * 10 % MOD
q10 = [0] * (len(S) + 1)
for i in range(len(S)):
q10[i + 1] = (q10[i] + p10[i]) % MOD
ans = 0
sofar, remain = 0, len(list(filter(lambda c: c.isdigit(), S)))
for t in S.split("+"):
p, q = 1, 0
ts = t.split("*")
for i in range(len(ts)):
u = ts[i]
remain -= len(u)
v, w = 0, 0
for j in range(len(u) - 1, -1, -1):
l = j + 1 + q + p * sofar
r = q10[len(u) - j]
if i == len(ts) - 1:
r += p10[len(u) - 1 - j] * remain
ans = (ans + int(u[j]) * l * r) % MOD
v = (v + int(u[j]) * p10[len(u) - 1 - j]) % MOD
w = (w + v) % MOD
p = p * v % MOD
q = (q * v + w) % MOD
sofar += len(t) - t.count("*")
print(ans)