扫描相邻差值,前后变化方向相反的中间位置就是折点。
OJ: shumeng
题目 ID: CSP201604A
难度:入门
标签:模拟数组
日期: 2026-07-31 16:21
形式化题目
给定
思路
第
判断一个位置
记两个相邻差值:
- 先增后减:
且 ; - 先减后增:
且 。
两种情况都等价于
扫描所有中间位置
端点
代码
cpp
/**
* Author by Rainboy blog: https://rainboylv.com github: https://github.com/rainboylvx
* rbook: -> https://rbook.roj.ac.cn https://rbook2.roj.ac.cn
* rainboy的学习导航网站: https://idx.roj.ac.cn
* create_at: 2026-07-31 16:21
* update_at: 2026-08-17 22:48
*/
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1005;
int n;
int sales[MAXN]; // 每天的销售量
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> sales[i];
}
int answer = 0;
// 第 i 天是折点,当且仅当前一段与后一段的增减方向相反。
// 相邻两天的销量保证不同,因此两个差值乘积为负就说明方向相反。
for (int i = 2; i <= n - 1; i++) {
int diff1 = sales[i] - sales[i - 1];
int diff2 = sales[i + 1] - sales[i];
if (diff1 * diff2 < 0) {
answer++;
}
}
cout << answer << '\n';
return 0;
}复杂度
- 时间:扫描每个中间位置做常数次比较,时间复杂度为
。 - 空间:需要保存全部
个销量,空间复杂度为 。
总结
折点判断可以统一为相邻差值乘积的符号,峰值和谷值共用同一条判断。注意端点缺少前后两天,不能计入答案。
