CF2068H. Statues

CF2068H. Statues

构造题.

思路

我们设 \(d_0 = a + b\) 是第 1 座雕像到第 \(n\) 座雕像的距离. 那么首先可以注意到两个必要条件:

  • \(\displaystyle \sum_{i = 0}^{n - 1} d_i\) 为偶数.
  • 对于 \(\forall i \in [0, n - 1]\), 都有 \(d_i \le d_0 + \dots + d_{i - 1} + d_{i + 1} + \dots d_{n - 1}\).

先来证明一下第一个.

可以发现

\[\displaystyle \sum_{i = 0}^{n - 1} d_i = (|x_0 - x_n| + |y_0 - y_n|) + (|x_1 - x_0| + |y_1 - y_0|) + \dots + (|x_n - x_{n - 1}| + |y_n - y_{n - 1}|) \]

将原式对 2 取模, 那么绝对值就没有意义了, 所以所有项都相互抵消了, 等价于 \(\displaystyle \sum_{i = 0}^{n - 1} d_i \equiv 0 \pmod 2\), 得证.

再来证明一下第二个条件, 根据三角形不等式可得.

证明完成, 我们来考虑怎么构造.

我们定义 \(d'_0 = d_1 + \dots + d_{n - 2}\) 为 1 号点到 \(n - 1\) 号点的距离. 那么我们需要证明 \(d'_0 + d_1 + \dots + d_{n - 2}\)​ 同样满足上面的必要条件. 第一个条件显然, 困难的是证明第二个.

由三角不等式可得, \(d'_0\) 可以取 \([|d_0 - d_{n - 1}|, d_0 + d_{n - 1}]\) 中所有与 \(d_0 + d_{n - 1}\) 奇偶性相同的值. 也就是如下图中的红点所示.

来证明一下 \(d'_0 = \min(d_0 + d_{n - 1}, d_1 + \dots d_{n - 2})\) 属于 \([|d_0 - d_{n - 1}|, d_0 + d_{n - 1}]\) 并且具有正确的奇偶性.

image.png

代码
#include "iostream"

using namespace std;

#define int long long

int n, a, b, d[51];

void init() {
	cin >> n >> a >> b;
}

void calculate() {
	int sum = a + b;
	for (int i = 1; i < n; i++) cin >> d[i], sum += d[i];
	if (sum & 1) return cout << "NO", void();
	if (sum - a - b < a + b) return cout << "NO", void();
	for (int i = 1; i < n; i++) if (sum - d[i] < d[i]) return cout << "NO", void();
	cout << "YES\n";
	cout << 0 << ' ' << 0 << '\n';
	int tot = sum / 2 - a - b, x = 0, y = 0;
	for (int i = 1; i < n; i++) {
		if (d[i] <= tot) {
			tot -= d[i];
			y -= d[i];
		} else if (tot) {
			if (d[i] - tot > a) {
				x = tot + a;
				y += d[i] - tot - a;
			} else {
				x += d[i] - tot;
				y -= tot;
			}
			tot = 0;
		} else {
			if (x > a) {
				if (x - d[i] < a) {
					y += d[i] - (x - a);
					x = a;
				} else {
					x -= d[i];
				}
			} else if (x < a) {
				if (x + d[i] > a) {
					y += d[i] - (a - x);
					x = a;
				} else {
					x += d[i];
				}
			} else y += d[i];
		}
		cout << x << ' ' << y << '\n';
	}
}

void solve() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr), cout.tie(nullptr);
	init();
	calculate();
}

signed main() {
	solve();
	return 0;
}
posted @   Steven1013  阅读(4)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示