ABC 338

手有点答辩,老是按错键,多吃了 \(2\) 罚时/cf

link

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)
posted @ 2024-01-28 22:31  123wwm  阅读(106)  评论(0)    收藏  举报