1 条题解
-
0
解决思路
- 好数序列分析:
- 如果公差 ,序列递减,需将 转化为第 项的值,将 取绝对值以便统一处理递增序列。
- 转化后,序列形式为 。
- 二分查找:
- 将好数序列视为一个递增数组,使用二分查找定位 在序列中的最近位置。
- 二分查找的目标是找到一个索引 ,使得 最接近 。
- 检查附近的项:
- 由于二分查找找到的位置可能不是最优解,还需检查二分附近的几项(例如 ),找出与 的最小绝对差。
- 时间复杂度:
- 构造序列的一般项计算复杂度为 。
- 二分查找的时间复杂度为 。
- 最多检查 10 项附近值,时间复杂度为常数级。
- 总复杂度为 。
代码详解
- 输入数据预处理:
- 如果 ,将序列起始值 转化为最后一项 ,并将 取绝对值。
- 这样,序列转化为递增序列。
- 二分查找:
- 定义查找范围为 ,取中间值计算该项对应的数值。
- 比较中间项和 的大小,调整查找范围,直到找到最近的位置。
- 周边值检查:
- 检查二分查找附近的几项(例如 到 ,确保不越界),计算与 的绝对差。
- 输出结果:
- 输出最小绝对差。
#include<bits/stdc++.h> using namespace std; int main() { ios::sync_with_stdio(0); cin.tie(0); long long x, a, d, n; cin >> x >> a >> d >> n; // 处理递减序列,将其转为递增序列 if (d < 0) { a = a + d * (n - 1); d = -d; } // 二分查找最近的项 long long l = 0, r = n - 1; while (l <= r) { long long m = (l + r) / 2; if (a + d * m < x) { l = m + 1; } else { r = m - 1; } } // 检查附近的项 long long res = LLONG_MAX; for (long long i = max(0LL, l - 5); i <= min(n - 1, l + 5); i++) { res = min(res, abs(a + d * i - x)); } // 输出结果 cout << res << '\n'; return 0; }
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); long x = sc.nextLong(); long a = sc.nextLong(); long d = sc.nextLong(); long n = sc.nextLong(); // 转换递减为递增序列 if (d < 0) { a = a + d * (n - 1); d = -d; } // 二分查找最近的位置 long l = 0, r = n - 1; while (l <= r) { long m = (l + r) / 2; if (a + d * m < x) { l = m + 1; } else { r = m - 1; } } // 检查附近的值 long res = Long.MAX_VALUE; for (long i = Math.max(0, l - 5); i <= Math.min(n - 1, l + 5); i++) { res = Math.min(res, Math.abs(a + d * i - x)); } // 输出结果 System.out.println(res); } }
def closest_good_number(x, a, d, n): # 转换递减为递增序列 if d < 0: a = a + d * (n - 1) d = -d # 二分查找最近的位置 l, r = 0, n - 1 while l <= r: m = (l + r) // 2 if a + d * m < x: l = m + 1 else: r = m - 1 # 检查附近的值 res = float('inf') for i in range(max(0, l - 5), min(n - 1, l + 5) + 1): res = min(res, abs(a + d * i - x)) # 输出结果 return res # 输入 x, a, d, n = map(int, input().split()) print(closest_good_number(x, a, d, n))
- 好数序列分析:
- 1
信息
- ID
- 234
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 9
- 标签
- 递交数
- 60
- 已通过
- 5
- 上传者