作业介绍

2026年编程兔冬令营集训第六场作业

1、双指针

2、滑动窗口

概念与核心思想
双指针:是一种通过设置两个指针(通常为数组或链表的索引)来遍历数据结构的技巧。两个指针的移动方式和条件根据具体问题而定,可用于解决多种问题,如查找、比较、合并等。
滑动窗口:是双指针的一种特殊应用形式,核心是维护一个“窗口”(即数组或字符串的连续子区间),通过动态调整窗口的左右边界(即两个指针)来寻找满足特定条件的子数组或子串。

1、这题有不同的做法。这介绍双指针。通过维护一个滑动窗口(区间),动态调整窗口的左右边界,使得窗口内数字的和与目标值进行比较,从而高效地找到所有满足条件的连续自然数段。S=[l,r]区间的总和;
如果S<M,则++l,S+=r;
如果S=M,则输出++r,S+=r;
如果S>M,则S-=l,++l
一直重复以上操作,直到l>M/2
#include<bits/stdc++.h>
using namespace std;

int main() {
    int m;
    cin >> m;
    int l = 1, r = 2;
    long long sum = l + r; // 使用 long long 避免溢出

    while (l <= m / 2) {
        if (sum == m) {
            cout << l << " " << r << endl;
            sum -= l;
            l++;
        } else if (sum < m) {
            r++;
            sum += r;
        } else {
            sum -= l;
            l++;
        }
    }
    return 0;
}
2、假设a[last]到a[i-1]都是不重复的数字,则有
a.当a[i]也是不重复的,则可以加到范围里面,last到i的数字都是不重复的;
b.如果a[i]在a[last]到a[i-1]出现过,出现的位置位j,则last=j+1,last到i的数字都是不重复的。
在b中问题就转化为如何快速的找到j的位置也就是a[i]前面出现的位置?
unordered_map可以解决这个问题。
#include<bits/stdc++.h>
using namespace std;
unordered_map<int,int> mp;//记录每个数上次出现的位置 ,不需要排序 
int n,x,ans =0,last=1;
int a[1000005];
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;++i){
		scanf("%d",&a[i]);
		if (mp[a[i]]){//last到i-1之间出现过a[i],则last直接指向上次a[i]出现的位置加1 
			while(last<=mp[a[i]]){
				mp[a[last]]=0;
				++last;
			}
		}
		ans = max(ans, i-last+1);
		mp[a[i]] = i;
	}
	printf("%d",ans);
	return 0;
}
3、假设a[last]到a[i-1]都是一样的数字,则有
c.当a[i]=a[i-1],last到i的数字都是一样的;
d.如果a[i]!=a[i-1],则输出[last,i-1]。
#include<bits/stdc++.h>
using namespace std;
int n,x,y,ans =0,last=1;
int main(){
	scanf("%d",&n);
	scanf("%d",&y);
	for(int i=2;i<=n;++i){
		scanf("%d",&x);
		if (x!=y){
			printf("%d %d\n",last,i-1);
			last = i;
			y=x;
		}
	}
	printf("%d %d\n",last,n);
	return 0;
}
4、思考一下这题是否可以借鉴第二题的一些思路?
unordered_map<int,int> mp;来统计x出现的次数,mp[x]++或者mp[x]--
#include<bits/stdc++.h>
using namespace std;
unordered_map<int,int> mp;//记录每个数的次数 
int n,k,ans =0;
int a[1000005];
int main(){
	scanf("%d%d",&n,&k);
	for(int i=1;i<=n;++i){
		scanf("%d",&a[i]);
		++mp[a[i]];//增加a[i]出现的次数 
	
		if (i>=k){
			if (i>k){
				--mp[a[i-k]];//减少a[i-k]出现的次数 
				//如果a[i-k]出现的次数为0,则清除a[i-k] 
				if (mp[a[i-k]]==0) mp.erase(a[i-k]);
			}
			int num = mp.size();
			ans = max(ans, num);
		}
	}
	printf("%d",ans);
	return 0;
}

题目

认领作业后才可以查看作业内容。
状态
正在进行…
题目
4
开始时间
2026-2-6 0:00
截止时间
2027-1-1 23:59
可延期
24 小时