尺取法及例题、习题大全

例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;
}

例2、洛谷P1102

具体解析见这里:

posted @ 2024-06-04 17:23  胖柚の工作室  阅读(27)  评论(0)    收藏  举报