尺取法及例题、习题大全
例1、洛谷P1147
正整数数序列自然有序,考虑双指针。
用 \(i,j\) 代表区间的左右端点
当 \(\rm sum\) 小于目标值 \(M\) 时,将右端点右移(j++),\(\rm sum\) 会变大
当 \(\rm sum\) 大于目标值 \(M\) 时,将左端点右移(i++),\(\rm sum\) 会变小
在双指针移动的过程中,如果有 sum==M 的情况就输出。
因为两个指针都是单调向右移动,也只扫一遍,可以证明时间复杂度为 \(O(n)\)
#include <bits/stdc++.h>
using namespace std;
using i64 = long long;
int main()
{
ios::sync_with_stdio(false), cin.tie(nullptr);
int M;
cin >> M;
int i = 1, j = 2, sum = 3;//初始时sum = i + j = 3
while (i < j) {//区间长度至少为2
if (sum < M) {
j++;
sum += j;
} else {
if (sum == M) cout << i << " " << j << "\n";
sum -= i;
i++;//i++, j++ 和 sum += j, sum -= i的相对位置不能改变
}
}
return 0;
}

浙公网安备 33010602011771号