题解:学而思编程 零距离
【题目来源】
学而思编程:零距离
【题目描述】
小猴最近刚刚在数学课上学完负数,老师给小猴布置了一个任务:有 \(n\) 个整数\(a_1,a_2,\dots,a_n\),要求找出其中最接近 \(0\) 的数字。如果有多种可能,只需要给出其中最大的数字。
【输入】
第一行一个整数 \(n\);
第二行n个整数\(a_1,a_2,\dots,a_n\)。
【输出】
一行一个整数,表示最接近0的数字。
【输入样例】
5
-4 -2 1 4 8
【输出样例】
1
【核心思想】
-
问题分析:给定 \(n\) 个整数,找出最接近 \(0\) 的数字。若绝对值相同,取较大的那个。这是一个线性扫描 + 绝对值比较问题,关键在于同时维护绝对值最小和数值最大的两个条件。
-
算法选择:
- 单变量维护:用
minn同时记录当前最优解,比较时先比绝对值,绝对值相同时比原值 - 贪心更新:遍历每个数,若更优则替换
- 单变量维护:用
-
关键步骤:
- 初始化:读取 \(n\)
minn = +\infty(极大值)- 线性扫描:
- 遍历 \(i\) 从 \(1\) 到 \(n\):
- 读取 \(a\)
- 若 \(|a| < |minn|\):
minn = a(绝对值更小,更新) - 否则若 \(|a| = |minn|\) 且 \(a > minn\):
minn = a(绝对值相同,取较大值)
- 遍历 \(i\) 从 \(1\) 到 \(n\):
- 输出
minn
-
时间/空间复杂度:
- 时间复杂度:\(O(n)\),线性扫描
- 空间复杂度:\(O(1)\),仅需一个变量
-
贪心扫描的核心思想:
- 双重比较条件:第一关键字为绝对值(越小越优),第二关键字为原值(越大越优),天然对应"最接近 \(0\) 且最大"的要求
- 单变量状态压缩:无需存储所有数,当前最优解
minn已包含足够信息,新数只需与之比较 - 流式处理:支持在线输入,无需预存全部数据
- 绝对值函数:
abs()统一处理正负数,避免分支判断 - 适用于"单目标极值 + 平局打破"类问题,线性扫描配合双重比较即可解决
【算法标签】
模拟
【代码详解】
#include <bits/stdc++.h>
using namespace std;
int main()
{
int n;
cin >> n; // 输入数字个数
int minn = 1e9; // 初始化最小值,使用较大的数
for (int i = 1; i <= n; i++) // 遍历n个数
{
int a;
cin >> a; // 输入当前数
// 如果绝对值更小,更新minn
if (abs(a) < abs(minn))
{
minn = a;
}
// 如果绝对值相等,取较大的数
if (abs(a) == abs(minn))
{
minn = max(minn, a);
}
}
cout << minn; // 输出结果
return 0;
}
【运行结果】
5
-4 -2 1 4 8
1
浙公网安备 33010602011771号