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


A. Function Height

题意:\(n\)个数给他们赋值,使得和恰好为\(k\), 求其中的最大值最小。

点击查看代码
void solve() {
    i64 n, k;
    std::cin >> n >> k;
    std::cout << (k + n - 1) / n << "\n";
}

B. Diagonal Walking v.2

题意:从\((0, 0)\)走到\((n, m)\)恰好走\(k\)步,可以走八个方向。求最多可以走几条斜边。

首先要发现,到了\((n, m)\)后如果剩下步数是偶数可以一直斜着来回走。
假设\(n >= m\),先斜着走\(m\)步到\((m, m)\)
那么如果\(n - m\)是奇数,那么如果剩下奇数步,我们向上走一步,就变成了剩下步数和到终点距离都是偶数,于是剩下步数都可以走斜边。如果剩下步数是偶数,我们可以向左或者向右走一步,然后斜着向上一步,剩下步数和到终点距离就都是偶数。于是这个情况答案就是\(k-1\)
否则如果\(n - m\)是偶数,如果剩下奇数步,则我们只能通过水平移动一次向上移动一次来缓冲,这样少了两步,答案是\(k-2\),否则就是\(k\)

点击查看代码
void solve() {
	i64 n, m, k;
	std::cin >> n >> m >> k;
	if (n < m) {
		std::swap(n, m);
	}

    if (k < n) {
    	std::cout << -1 << "\n";
    	return;
    }

    int d = k - m;
    if (n - m & 1) {
    	if (d & 1) {
    		std::cout << k - 1 << "\n";
    	} else {
    		std::cout << k - 1 << "\n";
    	}
    } else {
    	if (d & 1) {
    		std::cout << k - 2 << "\n";
    	} else {
    		std::cout << k << "\n";
    	}
    }
}

C. Classy Numbers

题意:求\([L, R]\)这个区间有多少数数位中非零数不超过三。

数位\(dp\)\(f[i][cnt]\)表示到第\(i\)为有\(cnt\)个非零数的答案。

点击查看代码
void solve() {
	i64 l, r;
	std::cin >> l >> r;

	std::vector f(20, std::array<i64, 4>{-1, -1, -1, -1});
	auto dp = [&](i64 n) -> i64 {
		std::string s;
		do {
			s += (char)(n % 10 + '0');
			n /= 10;
		} while (n);

		auto dfs = [&](auto & self, int u, int cnt, bool limit) -> i64 {
			if (cnt > 3) {
				return 0;
			}

			if (u == -1) {
				return 1;
			}

			if (f[u][cnt] != -1 && !limit) {
				return f[u][cnt];
			}

			int up = limit ? s[u] - '0' : 9;
			i64 res = 0;
			for (int i = 0; i <= up; ++ i) {
				res += self(self, u - 1, cnt + (i != 0), limit && i == up);
			}

			if (!limit) {
				f[u][cnt] = res;
			}

			return res;
		};

		return dfs(dfs, (int)s.size() - 1, 0, true);
	};

	std::cout << dp(r) - dp(l - 1) << "\n";
}

D. Vasya and Arrays

题意:给你两个数组,把他们划分成\(k\)份,使得从左到右对应的每一份和相等。使得\(k\)最大。

模拟,记录两个和以及加到了哪个数,然后讨论哪个和小就加哪个数组的数。

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

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

    int ans = 0;
    int i = 0, j = 0;
    i64 sa = 0, sb = 0;
    while (i < n || j < m) {
    	if (sa < sb) {
    		if (i == n) {
    			break;
    		}
    		sa += a[i ++ ];
    	} else if (sa > sb) {
    		if (j == m) {
    			break;
    		}
    		sb += b[j ++ ];
    	} else {
    		if (i == n || j == m) {
    			break;
    		}

    		if (a[i] > b[j]) {
    			sa = a[i ++ ];
    		} else {
    			sb = b[j ++ ];
    		}
    	}

    	if (sa == sb) {
    		++ ans;
    		sa = sb = 0;
    	}
    }

    if (i != n || j != m || sa != sb) {
    	std::cout << -1 << "\n";
    } else {
	    std::cout << ans << "\n";
    }
}
posted @ 2025-04-04 20:54  maburb  阅读(12)  评论(0)    收藏  举报