VP Educational Codeforces Round 63 (Rated for Div. 2)


A. Reverse a Substring

题意:翻转字符串一个子串,使得新字符串比原字符串字典序小。

交换相邻的就行,判断有没有相邻的\(i\)使得\(a_i > a_{i + 1}\)

点击查看代码
void solve() {
    int n;
    std::cin >> n;
    std::string s;
    std::cin >> s;
    for (int i = 0; i + 1 < n; ++ i) {
    	if (s[i] > s[i + 1]) {
    		std::cout << "YES\n";
    		std::cout << i + 1 << " " << i + 2 << "\n";
    		return;
    	}
    }

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

B. Game with Telephone Numbers

题意:一个数字串,两个人轮流操作,每次删去一个字符,留\(11\)个字符,你先手。求最后能不能使得第一个字符是\(8\)

对手肯定从左到右删去前面的\(8\)。求出操作次数为\(k\),那么判断第\(k + 1\)\(8\)前面不是\(8\)的数是不是小于等于\(k\)

点击查看代码
void solve() {
    int n;
    std::cin >> n;
    std::string s;
    std::cin >> s;
    int op = (n - 11) / 2;
    if (n == 11) {
    	std::cout << (s[0] == '8' ? "YES" : "NO") << "\n";
    	return;
    }

    for (int i = 0, j = 0; i < n; ++ i) {
    	j += s[i] == '8';
    	if (j == op + 1) {
    		if (i - op > op) {
    			std::cout << "NO\n";
    		} else {
    			std::cout << "YES\n";
    		}
    		return;
    	}
    }

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

C. Alarm Clocks Everywhere

题意:给你一个等差序列的\(n\)个可能不连续的项,再给你\(m\)个公差选择,选一个合法的公差。

公差一定是两个项的差的因子,因此它最大是所有\(a_{i+1} - a_i\)的最大公约数。求出最大公约数,判断有没有一个公差是他的因子。

点击查看代码
void solve() {
    int n, m;
    std::cin >> n >> m;
    std::vector<i64> a(n), b(m);
    for (int i = 0; i < n; ++ i) {
    	std::cin >> a[i];
    }

    for (int i = 0; i < m; ++ i) {
    	std::cin >> b[i];
    }

    i64 d = 0;
    for (int i = 1; i < n; ++ i) {
    	d = std::gcd(d, a[i] - a[i - 1]);
    }

    for (int i = 0; i < m; ++ i) {
    	if (d % b[i] == 0) {
    		std::cout << "YES\n";
    		std::cout << a[0] << " " << i + 1 << "\n";
    		return;
    	}
    }

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

D. Beautiful Array

题意:给你一个数组,最多操作一次把一个子数组都乘上\(x\)。求最大子段和。

\(f[i][0/1/2]\)为没有乘\(x\)、正在乘\(x\),已经结束乘\(x\)的最大值。那么\(f[i][0] = \max(0, f[i - 1][0] + a_i)\)。这个就是朴素的求最大子段和。\(f[i][1] = \max(0, f[i][0], f[i - 1][1] + a_i \times x)\),意为若干从当前开始分隔乘不乘\(x\),则是\(f[i][0]\),否则前面已经乘上\(x\)了,则是\(f[i - 1][1] + a_i \times x\)。然后是\(f[i][2] = \max(0, f[i][1], f[i - 1][2] + a_i)\)。和\(f[i][1]\)同理。

点击查看代码
void solve() {
    int n, x;
    std::cin >> n >> x;
    std::vector<i64> a(n);
    for (int i = 0; i < n; ++ i) {
    	std::cin >> a[i];
    }

    i64 ans = 0;
    std::array<i64, 3> f{};
    for (int i = 0; i < n; ++ i) {
	    std::array<i64, 3> g{};
	    g[0] = std::max(0ll, f[0] + a[i]);
	    g[1] = std::max({0ll, g[0], f[1] + a[i] * x});
	    g[2] = std::max({0ll, g[1], f[2] + a[i]});
	    ans = std::max({ans, g[0], g[1], g[2]});
	    f = g;
    }

    std::cout << ans << "\n";
}
posted @ 2025-04-20 18:24  maburb  阅读(10)  评论(0)    收藏  举报