[语言月赛 202312] 函数零点 的题解
记住只在没有思路时使用题解,不要从它复制粘贴代码。请尊重题目和题解的作者。
在解题之前提交题解的代码会导致封禁。
在解题之前提交题解的代码会导致封禁。
作者:
概述
本题要求根据相邻整数点函数值的符号变化,利用零点存在定理确定区间 内至少有多少个零点。核心解法是统计相邻点函数值乘积为负的次数,每出现一次即至少存在一个零点。
分析
核心观察
零点存在定理指出,若连续函数在两个端点处的函数值异号,则区间内至少有一个零点。因此,只需检查所有相邻整数点 ,若
,则区间
内必有一个零点。不同区间相互独立,总零点数至少为这些区间的数量。
思路
设给定序列为 ,其中
且均非零。对于每个
,若
与
异号(即乘积为负),则根据零点存在定理,区间
内至少有一个零点。由于这些区间互不重叠,零点数量可累加。答案为满足
的
的个数。由于数据保证
,乘积符号可直接通过比较正负判断。
具体示例
样例序列 ,相邻异号对为:
异号 → 零点在
同号
异号 → 零点在
异号 → 零点在
同号 总计
个。
算法步骤
- 读取整数
N。 - 读取长度为
的数组
a,存储到
。
- 初始化计数器
cnt为。
- 遍历
i从到
:
- 若
a[i] * a[i+1] < 0,将cnt加。
- 若
- 输出
cnt。
复杂度分析
- 时间:
- 空间:
实现注意事项
- 函数值绝对值可达
,乘积可能达到
,需使用 64 位整数(
long long)存储以避免溢出。 - 输入数据保证所有值非零,因此无需处理零值情况,但比较符号时直接判断
(a[i] > 0) != (a[i+1] > 0)可避免乘法溢出,更安全。 N最大为,数组大小适中。
源代码
#include <iostream>
#include <vector>
using namespace std;
int main() {
int N;
cin >> N;
vector<long long> a(N + 1);
for (int i = 0; i <= N; ++i) {
cin >> a[i];
}
int ans = 0;
for (int i = 0; i < N; ++i) {
if ((a[i] > 0) != (a[i + 1] > 0)) {
++ans;
}
}
cout << ans << endl;
return 0;
}
N = int(input())
a = list(map(int, input().split()))
ans = 0
for i in range(N):
if (a[i] > 0) != (a[i + 1] > 0):
ans += 1
print(ans)
评论