EPIC Institute of Technology Round Summer 2025 (Codeforces Round 1036, Div. 1 + Div. 2)


A. Deranged Deletions

题意:给你一个数组\(a\),你可以删除一些元素。最后要求排序后的这个数组和这个数组没有一个位置是相同的。

留下两个数满足第一个数大于第二个数就行。可以暴力枚举。

点击查看代码
#include <bits/stdc++.h>

using i64 = long long;

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

	for (int i = 0; i < n; ++ i) {
		for (int j = i + 1; j < n; ++ j) {
			if (a[i] > a[j]) {
				std::cout << "YES\n";
				std::cout << 2 << "\n";
				std::cout << a[i] << " " << a[j] << "\n";
				return;
			}
		}
	}
	std::cout << "NO\n";
}

int main() {
	std::ios::sync_with_stdio(false), std::cin.tie(0), std::cout.tie(0);
	int t = 1;
	std::cin >> t;
	while (t -- ) {
		solve();
	}
	return 0;
}

B. Minimise Sum

题意:给你一个数组,你可以操作一次,选择\(i, j\)满足\(i < j\),然后把\(a_j\)加到\(a_i\)上,之后\(a_j = 0\)。求\(\sum_{i=1}^{n} min(a_1, .. ,a_i)\)最小。

显然操作后\([j, n]\)对应位置的前缀的最小值都是\(0\)。那么可以枚举\(j\)是哪个位置,除了\(a_2\)必须加到\(a_1\)上会影响\([1, 1]\)的最小值,其它都可以加到最大值的位置使得最小值不受影响。

点击查看代码
#include <bits/stdc++.h>

using i64 = long long;

void solve() {
	int n;
	std::cin >> n;
	std::vector<i64> a(n);
	for (int i = 0; i < n; ++ i) {
		std::cin >> a[i];
	}

	i64 sum = a[0] + std::min(a[0], a[1]), min = std::min(a[0], a[1]);
	i64 ans = a[0] + a[1];
	for (int i = 2; i < n; ++ i) {
		ans = std::min(ans, sum);
		min = std::min(min, a[i]);
		sum += min;
	}
	ans = std::min(ans, sum);
	std::cout << ans << "\n";
}

int main() {
	std::ios::sync_with_stdio(false), std::cin.tie(0), std::cout.tie(0);
	int t = 1;
	std::cin >> t;
	while (t -- ) {
		solve();
	}
	return 0;
}

C. Subset Multiplication

题意:给你一个数组\(b\),求一个\(x\),使得可以选出一些位置除以\(x\)后得到数组\(a\),所有\(a_i\)整除\(a_{i+1}\)。求一个合法的\(x\)

\(b_i\)要么等于\(a_i\)要么等于\(a_i \times x\),可以记\(t_i\)表示是否乘了\(x\)\(t_i = 0\)则没有乘,\(t_i = 1\)则乘了。
那么\(b_i = a_i \times x^{t_i}\)。记\(a_{i+1} = a_i \times c\)。那么\(gcd(b_i, b_{i+1}) = gcd(a_i \times x^{t_i}, a_{i} \times c \times x^{t_{i+1}}) = a_i \times x^{min(t_i, t_{i+1})}\)
我们用\(b_i\)除这个东西,就是\(\frac{a_i \times x^{t_i}}{a_i \times x^{min(t_i, t_{i+1}})} = x^{t_i - min(t_i, t_{i+1})}\),显然这个值要么是\(x\)要么是\(1\)。但不同相邻对得到的\(x\)可能不同,我们可以取它们的最小公倍数。

点击查看代码
#include <bits/stdc++.h>

using i64 = long long;

void solve() {
	int n;
	std::cin >> n;
	std::vector<i64> b(n);
	for (int i = 0; i < n; ++ i) {
		std::cin >> b[i];
	}

	i64 x = 1;
	for (int i = 0; i + 1 < n; ++ i) {
		i64 d = std::gcd(b[i], b[i + 1]);
		i64 v = b[i] / d;
		if (v > 1) {
			x = x / std::gcd(x, v) * v;
			if (x > 1e9) {
				x = v;
			}
		}
	}
	std::cout << x << "\n";
}

int main() {
	std::ios::sync_with_stdio(false), std::cin.tie(0), std::cout.tie(0);
	int t = 1;
	std::cin >> t;
	while (t -- ) {
		solve();
	}
	return 0;
}

D. Make a Palindrome

题意:给你一个数组,每次选择一个长度大于等于\(k\)的子区间,然后删掉第\(k\)小的数,如果有多少可以删任意一个。求能不能使得数组变成回文。

显然原数组第\(1\)\(k-1\)小不可能被删掉,假设得到了一个结果,那么我们可以把第\(k+1\)小及比它大的都删掉,依然符合条件。那么我们把第\(1\)到第\(k\)小的位置拿出来,问题变为删掉一些第\(k\)小的位置使得数组变成回文,注意数组长度最少为\(k - 1\)
这个可以通过双指针判断,每次找两侧不等于第\(k\)小的数,因为它们不能被删,所以每次找到的对必须相同。然后记录两侧第\(k\)小的数的个数的差异,因为我们要删去两侧一些数使得构成回文。那么删去的总数不能使得长度小于\(k-1\)

点击查看代码
#include <bits/stdc++.h>

using i64 = long long;

void solve() {
	int n, k;
	std::cin >> n >> k;
	std::vector<int> a(n);
	for (int i = 0; i < n; ++ i) {
		std::cin >> a[i];
	}

    auto b = a;
    std::ranges::sort(b);
    int x = b[k - 1];
    std::vector<int> c;
    for (int i = 0; i < n; ++ i) {
        if (a[i] <= x) {
            c.push_back(a[i]);
        }
    }   

    int m = c.size();
    int l = 0, r = m - 1;
    int len = m;
    while (l < r) {
        int cntl = 0;
        while (l < r && c[l] == x) {
            ++ l;
            ++ cntl;
        }

        int cntr = 0;
        while (r >= 0 && c[r] == x) {
            -- r;
            ++ cntr;
        }

        if (l > r) {
            std::cout << "YES\n";
            return;
        }

        if (c[l] != c[r]) {
            std::cout << "NO\n";
            return;
        }

        len -= std::abs(cntl - cntr);
        if (len < k - 1) {
            std::cout << "NO\n";
            return;
        }
        ++ l, -- r;
    }

    std::cout << "YES\n";
}

int main() {
	std::ios::sync_with_stdio(false), std::cin.tie(0), std::cout.tie(0);
	int t = 1;
	std::cin >> t;
	while (t -- ) {
		solve();
	}
	return 0;
}
posted @ 2025-07-07 01:43  maburb  阅读(305)  评论(0)    收藏  举报