Codeforces Round 886 (Div. 4) 题解

发布时间 2023-10-24 08:33:21作者: Svemit

link

我为什么还要 vp div4 场。。。

A

直接找最大的两个判断一下。

void solve() {
	int a[3];
	cin >> a[0] >> a[1] >> a[2];
	sort(a, a + 3);
	if(a[2] + a[1] >= 10) cout << "YES\n";
	else cout << "NO\n";
}

B

按照题目意思模拟。

void solve() {
	int n, ans, mx = 0;
	cin >> n;
	for(int i = 1; i <= n; i ++) {
		int a, b;
		cin >> a >> b;
		if(a <= 10) {
			if(b > mx) ans = i, mx = b;
		}
	}
	cout << ans << '\n';
}

C

直接从上往下从左往右遍历,遍历到字母的顺序一定是竖着的顺序。

void solve() {
	string s[8];
	for(int i = 0; i < 8; i ++) {
		cin >> s[i];
	}
	for(int i = 0; i < 8; i ++) 
		for(auto t : s[i]) 
			if(t != '.') cout << t;
	cout << '\n';
}

D

先对原数组排序,答案显然是一个块,保留最大的那个块即可。

void solve() {
	int n, k, ans = 1;
	cin >> n >> k;
	vector<int> a(n);
	for(int i = 0; i < n; i ++) cin >> a[i];
	sort(a.begin(), a.end());
	int cnt = 1;
	for(int i = 1; i < n; i ++) {
		if(a[i] - a[i - 1] > k) {
			cnt = 1;
		}
		else cnt ++;
		ans = max(ans, cnt);
	}
	cout << n - ans << '\n';
}

E

由题意得到一个方程:

\[\sum_{i=1}^n (s_i+w \times 2)^2 = c \]

然后解二次方程。

void solve() {
	LL n;
	LL a;
	cin >> n >> a;
	__int128 c = a, sum = 0;
	for(int i = 0; i < n; i ++) {
		LL x;
		cin >> x;
		sum += x;
		c -= x * x;
	}
	c /= 4;
	cout << (LL)(sqrtl(sum * sum + 4 * n * c) - sum) / (2ll * n) << '\n';
}

F

首先 \(n < a_i\) 的对答案一定没有贡献,考虑把每个数出现的次数存起来,把这个数的倍数的答案全部加上次数,最后输出答案的最大值即可。

void solve() {
	int n;
	cin >> n;
	vector<int> cnt(n + 1), res(n + 1);
	for(int i = 0; i < n; i ++) {
		int x;
		cin >> x;
		if(x <= n) cnt[x] ++;
	}
	for(int i = 1; i <= n; i ++)
		for(int j = i; j <= n; j += i) 
			res[j] += cnt[i];
	cout << *max_element(res.begin(), res.end()) << '\n';
}

G

emm...直接用 \(k, b\) 存直线就行。

为了方便平行于 \(y\) 轴的直线的 \(k = 2\)

void solve() {
	int n;
	LL res = 0;
	cin >> n;
	vector<PII> a(n);
	map<PII, int> mp;
	for(int i = 0; i < n; i ++) {
		cin >> a[i].fi >> a[i].se;
		res += mp[{1, a[i].se - a[i].fi}];
		res += mp[{-1, a[i].fi + a[i].se}];
		res += mp[{0, a[i].se}];
		res += mp[{2, a[i].fi}];
		mp[{1, a[i].se - a[i].fi}] ++;
		mp[{-1, a[i].fi + a[i].se}] ++;
		mp[{0, a[i].se}] ++;
		mp[{2, a[i].fi}] ++;
	}
	cout << res * 2ll << '\n';
}

H

边带权并查集板子???

int n, m;
int fa[N];
LL dist[N];
int find(int x) {
	if(fa[x] == x) return x;
	int rt = find(fa[x]);
	dist[x] += dist[fa[x]];
	return fa[x] = rt;
}
bool same(int x, int y) {
	return find(x) == find(y);
}
void merge(int x, int y, int v) {
	int fx = find(x), fy = find(y);
	dist[fx] = dist[y] + v - dist[x];
	fa[fx] = fy;
}
void solve() {
	cin >> n >> m;
	bool ok = true;
	for(int i = 1; i <= n; i ++) fa[i] = i, dist[i] = 0;
	while(m --) {
		int a, b, d;
		cin >> a >> b >> d;
		if(!ok) continue;
		if(same(a, b)) {
			if(dist[a] - dist[b] != d) ok = false;
		}
		else {
			merge(a, b, d);
		}
	}
	if(ok) cout << "YES\n";
	else cout << "NO\n";
}