鱼C论坛

 找回密码
 立即注册
查看: 2031|回复: 5

C++

[复制链接]
发表于 2023-11-29 21:58:11 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
描述
在一个非降序列中,查找与给定值最接近的元素。

输入
第一行包含一个整数n,为非降序列长度。1 <= n <= 100000。
第二行包含n个整数,为非降序列各元素。所有元素的大小均在0-1,000,000,000之间。
第三行包含一个整数m,为要询问的给定值个数。1 <= m <= 10000。
接下来m行,每行一个整数,为要询问最接近元素的给定值。所有给定值的大小均在0-1,000,000,000之间。
输出
m行,每行一个整数,为最接近相应给定值的元素值,保持输入顺序。若有多个值满足条件,输出最小的一个。
样例输入
3
2 5 8
2
10
5
样例输出
8
5
C++
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2023-11-29 21:58:29 | 显示全部楼层
可以使用二分查找的方法来解决这个问题。首先,我们需要定义一个函数来查找与给定值最接近的元素:
  1. int findClosestElement(int arr[], int n, int target) {
  2.     int left = 0;         // 左边界
  3.     int right = n - 1;    // 右边界
  4.    
  5.     // 当左边界小于右边界时,重复查找
  6.     while (left < right) {
  7.         int mid = left + (right - left) / 2;    // 中间元素索引
  8.         
  9.         // 如果中间元素等于目标值,则直接返回
  10.         if (arr[mid] == target) {
  11.             return mid;
  12.         }
  13.         
  14.         // 如果中间元素大于目标值,则将右边界移动到中间元素的左边
  15.         if (arr[mid] > target) {
  16.             right = mid;
  17.         }
  18.         
  19.         // 如果中间元素小于目标值,则将左边界移动到中间元素的右边
  20.         else {
  21.             left = mid + 1;
  22.         }
  23.     }
  24.    
  25.     // 当循环结束时,左边界即为最接近目标值的元素索引
  26.     return left;
  27. }
复制代码

然后,我们可以读入输入数据并调用该函数进行查找:
  1. #include <iostream>
  2. using namespace std;
  3. int main() {
  4.     int n;    // 序列长度
  5.     cin >> n;
  6.    
  7.     int arr[n];    // 序列数组
  8.    
  9.     // 读入序列数据
  10.     for (int i = 0; i < n; i++) {
  11.         cin >> arr[i];
  12.     }
  13.    
  14.     int target;    // 目标值
  15.     cin >> target;
  16.    
  17.     // 查找最接近目标值的元素索引
  18.     int closestIndex = findClosestElement(arr, n, target);
  19.    
  20.     cout << "最接近目标值的元素为:" << arr[closestIndex] << endl;
  21.    
  22.     return 0;
  23. }
复制代码

这样,我们就可以通过输入一个非降序列和一个目标值,找到与目标值最接近的元素。

以上回复来自 -- ChatGPT(FishC官方接口),如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-11-29 21:58:34 | 显示全部楼层
用二分查找
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-11-29 21:58:59 | 显示全部楼层

好的,我们可以使用二分查找算法来实现。下面是用二分查找来查找与给定值最接近的元素的完整代码:
  1. #include <iostream>
  2. #include <vector>
  3. #include <cmath>
  4. using namespace std;
  5. // 二分查找函数
  6. int binarySearch(const vector<int>& arr, int target) {
  7.     int left = 0;           // 左边界
  8.     int right = arr.size() - 1;    // 右边界
  9.    
  10.     while (left <= right) {
  11.         int mid = left + (right - left) / 2;   // 中间元素索引
  12.         
  13.         // 如果中间元素等于目标值,则直接返回
  14.         if (arr[mid] == target) {
  15.             return mid;
  16.         }
  17.         
  18.         // 如果中间元素大于目标值,则将右边界移动到中间元素的左边
  19.         if (arr[mid] > target) {
  20.             right = mid - 1;
  21.         }
  22.         
  23.         // 如果中间元素小于目标值,则将左边界移动到中间元素的右边
  24.         else {
  25.             left = mid + 1;
  26.         }
  27.     }
  28.    
  29.     // 当循环结束时,左边界即为最接近目标值的元素索引
  30.     return left;
  31. }
  32. // 查找与给定值最接近的元素
  33. int findClosestElement(const vector<int>& arr, int target) {
  34.     // 使用二分查找找到与目标值最接近的元素索引
  35.     int index = binarySearch(arr, target);
  36.    
  37.     // 检查最接近元素的左边元素和右边元素,返回距离目标值最接近的元素
  38.     if (index == 0) {
  39.         return arr[index];
  40.     }
  41.     else if (index == arr.size()) {
  42.         return arr[index - 1];
  43.     }
  44.     else {
  45.         if (abs(arr[index] - target) < abs(arr[index - 1] - target)) {
  46.             return arr[index];
  47.         }
  48.         else {
  49.             return arr[index - 1];
  50.         }
  51.     }
  52. }
  53. int main() {
  54.     int n;  // 序列长度
  55.     cin >> n;
  56.    
  57.     vector<int> arr(n); // 序列数组
  58.    
  59.     // 读入序列数据
  60.     for (int i = 0; i < n; i++) {
  61.         cin >> arr[i];
  62.     }
  63.    
  64.     int target; // 目标值
  65.     cin >> target;
  66.    
  67.     int closestElement = findClosestElement(arr, target); // 查找最接近目标值的元素
  68.    
  69.     cout << closestElement << endl;
  70.    
  71.     return 0;
  72. }
复制代码

这段代码首先定义了一个二分查找函数`binarySearch`,然后定义了一个`findClosestElement`函数用于查找与给定值最接近的元素。在主函数中,我们读入序列长度、序列数据和目标值,并调用`findClosestElement`函数来查找最接近目标值的元素,并将结果输出。

请注意,这里假设输入的序列是非降序排列的。如果需要处理其他类型的序列,请根据实际情况进行相应的调整。

以上回复来自 -- ChatGPT(FishC官方接口),如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-11-29 22:03:13 | 显示全部楼层
FishC_GPT 发表于 2023-11-29 21:58
好的,我们可以使用二分查找算法来实现。下面是用二分查找来查找与给定值最接近的元素的完整代码:

为什么当循环结束时,左边界即为最接近目标值的元素索引
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-11-29 22:03:27 | 显示全部楼层
黎子卿 发表于 2023-11-29 22:03
为什么当循环结束时,左边界即为最接近目标值的元素索 ...

在二分查找算法中,我们通过不断更新左边界和右边界来缩小查找范围,直到左边界等于右边界。这时候,我们已经找到了目标值的插入位置,即左边界所在的位置。

当循环结束时,如果目标值存在于数组中,那么左边界所在的位置就是该元素的索引。如果目标值不存在于数组中,那么左边界所在的位置就是离目标值最接近的元素的插入位置。

我们之所以选择左边界作为结果返回,是因为题目要求查找与给定值最接近的元素。在非降序列中,左边界一定比右边界更接近目标值,所以选择左边界即可。

需要注意的是,当数组中有多个与目标值最接近的元素时,返回左边界可能并不是唯一的正确答案。这种情况下,你可以根据题目要求进一步处理,如返回多个最接近的元素。

以上回复来自 -- ChatGPT(FishC官方接口),如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-6-9 00:29

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表