尺子長度 L,現有 N 個刻度 (N ≤ 10⁵)。女生標準 x,男生標準 y。可添加刻度。求最少添加幾個刻度,使能測量出距離 x 和 y (即存在兩刻度差為 x,且存在兩刻度差為 y)。輸出添加數量及具體位置 (任意合法方案)。
最多添加 x 和 y 兩個刻度即可滿足。故只需判斷:0 個、1 個、2 個 三種情況。
a[],排序 (輸入已保證遞增)。has(d):二分查找是否存在差為 d 的刻度對。對每個 a[i],查 a[i]+d 是否存在 (或 a[i]-d)。has(x) 和 has(y):
枚舉現有刻度 a[i] 作為參考,嘗試在 a[i] ± x 或 a[i] ± y 添加新刻度 pos,檢查新刻度與現有刻度能否構成另一距離。具體:
a[i] + x, a[i] - x, a[i] + y, a[i] - y (需在 [0, L] 內)。pos,檢查 has(pos ± x) 或 has(pos ± y) (排除自身)。pos。#include <bits/stdc++.h>
using namespace std;
const int MAXN = 100005;
int a[MAXN];
int n, L, x, y;
bool has(int val) {
if (val < 0 || val > L) return false;
int idx = lower_bound(a, a+n, val) - a;
return idx < n && a[idx] == val;
}
int main() {
scanf("%d%d%d%d", &n, &L, &x, &y);
for (int i = 0; i < n; i++) scanf("%d", &a[i]);
bool hx = false, hy = false;
for (int i = 0; i < n; i++) {
if (has(a[i] + x) || has(a[i] - x)) hx = true;
if (has(a[i] + y) || has(a[i] - y)) hy = true;
}
if (hx && hy) { puts("0"); return 0; }
if (hx) { puts("1"); printf("%d\n", y); return 0; }
if (hy) { puts("1"); printf("%d\n", x); return 0; }
// 嘗試加 1 個
for (int i = 0; i < n; i++) {
// 以 a[i] 為基準加 x
int pos = a[i] + x;
if (pos <= L && (has(pos - y) || has(pos + y))) {
puts("1"); printf("%d\n", pos); return 0;
}
pos = a[i] - x;
if (pos >= 0 && (has(pos - y) || has(pos + y))) {
puts("1"); printf("%d\n", pos); return 0;
}
// 以 a[i] 為基準加 y
pos = a[i] + y;
if (pos <= L && (has(pos - x) || has(pos + x))) {
puts("1"); printf("%d\n", pos); return 0;
}
pos = a[i] - y;
if (pos >= 0 && (has(pos - x) || has(pos + x))) {
puts("1"); printf("%d\n", pos); return 0;
}
}
// 必須加 2 個
puts("2");
printf("%d %d\n", x, y);
return 0;
}
has 函數需用 lower_bound 精確匹配,不可用 binary_search 直接判斷 (需確認存在)。