[语言月赛 202410] 刻度尺 的题解


记住只在没有思路时使用题解,不要从它复制粘贴代码。请尊重题目和题解的作者。
在解题之前提交题解的代码会导致封禁。

作者: admin

概述

本题要求找出刻度尺 0, 1, \ldots, n 上所有与刻度 a 距离恰好为 b 的刻度,按从小到大输出,不存在时输出 No solution。核心解法是列出满足 |x - a| = b 的两个候选刻度 a - b 与 a + b,再检查它们是否落在 [0, n] 范围内。

分析
核心观察

与刻度 a 距离为 b 的刻度只有两个候选:a - b 和 a + b,只需判断它们是否在 [0, n] 区间内;当 b = 0 时两者重合,只输出一个。

思路

由距离的定义,刻度 x 满足条件当且仅当:

\displaystyle  |x - a| = b

即 x = a - b 或 x = a + b。候选值还需满足 0 \le x \le n。由于 b \ge 0,恒有 a - b \le a + b,按此顺序收集即可保证从小到大输出。

具体示例

以样例 1 为例:n = 15、a = 9、b = 4,候选为 9 - 4 = 5 和 9 + 4 = 13,均落在 [0, 15] 内,输出 5、13。样例 2 中候选 8 - 100 = -92 与 8 + 100 = 108 均越界,因此输出 No solution。

算法步骤
  1. 读入 n、a、b。
  2. 计算候选刻度 x1 为 a - b、x2 为 a + b。
  3. 若 x1 在 [0, n] 内,将其加入答案。
  4. 若 x2 与 x1 不同且 x2 在 [0, n] 内,将其加入答案。
  5. 答案非空则从小到大输出;否则输出 No solution。
复杂度分析

时间:O(1)

空间:O(1)

实现注意事项
  • 当 b = 0 时,a - b 与 a + b 相等,需要去重,只输出一个 a。
  • 越界判断使用闭区间:刻度 0 与 n 都是合法刻度。
  • 输出要求整数间以单个空格分隔,行末无多余空格;无解时严格输出字符串 No solution。
源代码
#include <bits/stdc++.h>
using namespace std;

int main() {
    int n, a, b;
    cin >> n >> a >> b;

    vector<int> ans;
    int x1 = a - b, x2 = a + b;
    if (x1 >= 0 && x1 <= n) ans.push_back(x1);
    if (x2 != x1 && x2 >= 0 && x2 <= n) ans.push_back(x2);

    if (ans.empty()) {
        cout << "No solution\n";
    } else {
        for (int i = 0; i < (int)ans.size(); i++) {
            if (i) cout << ' ';
            cout << ans[i];
        }
        cout << '\n';
    }
    return 0;
}
n, a, b = map(int, input().split())
ans = []
for x in (a - b, a + b):
    if 0 <= x <= n and x not in ans:
        ans.append(x)
if not ans:
    print("No solution")
else:
    print(*ans)

评论

目前没有评论。