AtCoder Beginner Contest 069

A

题意

\(n\) 条横线和 \(m\) 条竖线,可以划分出多少个内部没有线条的矩形?

题解

单独考虑一维,\(n\) 条横线组成 \(n\) 个点,构成 \(n - 1\) 条边。另一维同理。答案是 \((n - 1) \times (m - 1)\)

如果增加一些难度。询问共可以划出多少个矩形,答案是 \(\binom{n}{2} \times \binom{m}{2}\)

再增加一些难度,询问所有矩形的面积之和。 需要解决经典的问题

\[\sum_{i = 1}^{n} \sum_{j = i + 1}^{n} (x_j - x_i) \times \sum_{i = 1}^{n} \sum_{j = i + 1}^{m} (y_j - y_i) \]

两个式子贡献独立,每个式子由组合贡献可以化为 \(O(n)\) 计算的式子。

B

题意

没什么新意的题,给一个字符串 \(s(|s| \geq 3)\) ,输出“首字符”+“字符串长度-2”+“尾字符”。

题解

	std::string s; std::cin >> s;
	std::cout << s[0] << s.size() - 2 << s.back() << "\n";

C

题意

给一个长度为 \(N\) 的正整数序列 \((a_1, a_2, \cdots, a_N)\) 。询问是否可以重排序列使其满足:

  • 对任意 \(1 \leq i \leq N - 1\)\(a_i \times a_{i + 1}\)\(4\) 的倍数。

题解

自己想到核心问题,但是还是不会讨论。

相邻两个数,要么有一个数存在质因子 \(2\) 且幂次 \(\geq 4\) ,要么两个数都存在质因子 \(2\) 且幂次是 \(2\)

一个好的思路(官方思路)。

\(\mathbb{1}\) 表示奇数。
\(\mathbb{2}\) 表示存在质因子 \(2\) 且幂次是 \(2\) 的数。
\(\mathbb{4}\) 表示存在质因子 \(2\) 且幂次 \(\geq 4\) 的数。

\(cnt(\mathbb{2}) = 0\) ,可以按照 \(\mathbb{1}\mathbb{4}\mathbb{1}\mathbb{4}\mathbb{1}\) 排列。需要 \(cnt(\mathbb{4}) \geq cnt(\mathbb{1}) - 1\)
因为保证了序列至少有两个数,所以不会出现 \(cnt(\mathbb{2}) = 0, cnt(\mathbb{4}) = 0, cnt(\mathbb{1}) = 1\)

\(cnt(\mathbb{1}) \neq 0\) ,可以按照 \(\mathbb{2}\mathbb{2}\mathbb{2}\mathbb{4}\mathbb{1}\mathbb{4}\mathbb{1}\mathbb{4}\mathbb{1}\) 。需要 \(cnt(\mathbb{4}) \geq cnt(\mathbb{1})\)

view
	int n; std::cin >> n;
	int a[5] = {0};
	for (int i = 1; i <= n; i++) {
		int x; std::cin >> x;
		if (x % 2 == 0 && x % 4 != 0) a[2]++;
		else if (x % 4 == 0) a[4]++;
		else a[1]++;
	}
	int ok = 0;
	if (a[2] == 0) {
		ok |= a[4] >= a[1] - 1;
	} else {
		ok |= a[4] >= a[1];
	}
	std::cout << (ok ? "Yes" : "No") << "\n";

D

题意

给一个 \(H \times W\) 的矩阵。给 \(N\) 种颜色,第 \(i\) 种颜色用 \(i\) 表示,需要填 \(a_i\) 个格子。保证 \(\sum_{i = 1}^{N} a_i = H \times W\)
要求将矩阵填满颜色,并且可以根据颜色划分四联通分量。

题解

感觉是非常直觉的构造,蛇形填充就行。

view
	int H, W, N; std::cin >> H >> W >> N;
	std::vector<std::vector<int> > g(H + 1, std::vector<int>(W + 1));
	int x = 1, y = 1, sgn = 1;
	for (int i = 1; i <= N; i++) {
		int c; std::cin >> c;
		for (int j = 1; j <= c; j++) {
			g[x][y] = i;
			y += sgn;
			if (y < 1 || W < y)
				x++, sgn *= -1, y += sgn;
		}
	}
	for (int i = 1; i <= H; i++) {
		for (int j = 1; j <= W; j++) {
			std::cout << g[i][j] << " \n"[j == W];
		}
	}
posted @ 2024-07-13 02:03  03Goose  阅读(28)  评论(0)    收藏  举报