SMU winter 2025 Personal Round 1

SMU winter 2025 Personal Round 1

A. Level Statistics

思路

注意两方增长值要确保 \(\Delta c\le \Delta p\)

代码

#include <bits/stdc++.h>

using namespace std;

using i64 = long long;

void solve() {

	int n;
	cin >> n;

	vector<array<int, 2>> pc(n);
	for (auto &[a, b] : pc) {
		cin >> a >> b;
	}

	if (pc[0][1] > pc[0][0]) {
		cout << "NO\n";
		return;
	}

	for (int i = 1; i < n; i ++) {
		if (pc[i][0] < pc[i - 1][0] || pc[i][1] < pc[i - 1][1] || pc[i][1] - pc[i - 1][1] > pc[i][0] - pc[i - 1][0] ) {
			cout << "NO\n";
			return;
		}
	}

	cout << "YES\n";

}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);

	int t;
	cin >> t;
	while (t--) {
		solve();
	}

	return 0;
}

B. Middle Class

思路

降序排序后,取前 \(i\) 个平均值大于 \(x\) 的即可。

代码

#include <bits/stdc++.h>

using namespace std;

using i64 = long long;

void solve() {

	int n, x;
	cin >> n >> x;

	vector<int> a(n);
	for (int i = 0; i < n; i ++) {
		cin >> a[i];
	}

	sort(a.begin(), a.end(), greater<>());

	i64 sum = 0, ans = 0;
	for (int i = 0; i < n; i ++) {
		sum += a[i];
		if (sum >= 1LL * (i + 1) * x) {
			ans = i + 1;
		}
	}

	cout << ans << "\n";

}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);

	int t;
	cin >> t;
	while (t--) {
		solve();
	}

	return 0;
}

C. Circle of Monsters

思路

要尽可能地减少攻击次数,那么就要就可能地让其爆炸,最好全部都爆炸。

那么我们可以处理出每个怪物和其上一个怪物爆炸产生的差值,这部分就是我们需要的攻击次数;然后再挨个去判断从哪个怪物开始攻击直至其生命力为 \(0\) 后产生连环爆炸所需要的最少攻击次数即可。

代码

#include <bits/stdc++.h>

using namespace std;

using i64 = long long;

void solve() {

	int n;
	cin >> n;

	vector<array<i64, 2>> a(n);
	for (auto &[x, y] : a) {
		cin >> x >> y;
	}

	i64 sum = 0, ans = LLONG_MAX;
	for (int i = 0; i < n; i ++) {
		sum += max(0LL, a[i][0] - a[(i - 1 + n) % n][1]);
	}

	for (int i = 0; i < n; i ++) {
		ans = min(ans, sum - max(0LL, a[i][0] - a[(i - 1 + n) % n][1]) + a[i][0]);
	}

	cout << ans << "\n";

}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);

	int t;
	cin >> t;
	while (t--) {
		solve();
	}

	return 0;
}

D. Minimum Euler Cycle

思路

先说结论,就是 \(1,2,1,3\dots1,n,2,3,2,4\dots2,n,3,4\dots n-1,n,1\).

可以看出,两个一组就是假设为 \([a,b]\),那么先是 \(a\)\(1\) 开始,然后是 \(b\)\(2\sim n\) ,循环完后 \(a+1\),此后 \(b\) 又从 \(a+2\sim n\),一直到最后的 \(1\)。所以我们能算出对于每个 \(i\) 来说,会有 \((n-i)\times2\) 个数,那么这一部分做前缀和,对于 \(l\) 二分一下就能找到起始位置了。

代码

#include <bits/stdc++.h>

using namespace std;

using i64 = long long;

void solve() {

	int n;
	i64 l, r;
	cin >> n >> l >> r;

	vector<i64> pre(n + 1);
	for (int i = 1; i <= n; i ++) {
		pre[i] += pre[i - 1] + 2 * (n - i);
	}

	pre[n] += 1;

	auto st = lower_bound(pre.begin() + 1, pre.end(), l) - pre.begin();

	int a = st, b = (l - pre[st - 1] + 1) / 2 + st;

	if (a == n) {
		a = 1;
	}

	for (i64 i = l; i <= r; i ++) {
		if (i & 1) {
			cout << a << " \n"[i == r];
		} else {
			cout << b << " \n"[i == r];
			b ++;
			if (b > n) {
				a ++;
				if (a >= n) {
					a = 1;
				}
				b = a + 1;
			}
		}
	}

}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);

	int t;
	cin >> t;
	while (t--) {
		solve();
	}

	return 0;
}
posted @ 2025-01-26 19:40  Ke_scholar  阅读(12)  评论(0)    收藏  举报