Wannafly模拟赛3 绝对半径2051(离散化+尺取法)

题目链接:点击打开链接

思路:题目求的为最大的连续相同数字的长度,也就是说,若把相同数字分到一组,组间没有太大联系,联系只发生在组内数字的相对位置上,那么就把每组数字的位置存储下来分别处理,因为数字最大可以到10^9,数组开不下,但n最大只有10^5,所以可以把这些数字映射到10^5内。具体处理每组数字时,可以采用尺取法,也可以理解为贪心求解,对于每个le,rig在条件限制内最大可能的右移使区间最大。

// 绝对半径2051 运行/限制:67ms/1000ms
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <map>
using namespace std;
vector<int> v[100005];//存储每个数(离散化后的)的位置
map<int, int> m;//用于离散化
int main(){
	int n, k, c;
	int cnt, re;
	while (scanf("%d%d", &n, &k) != EOF) {
		cnt = 0;
		m.clear();
		for (int i = 0; i < n; i++) {
			v[i].clear();
		}
		for (int i = 0; i < n; i++) {//读取数据并离散化,m[num]即为num离散化对应的数
			scanf("%d", &c);
			if (m.count(c) == 0) {
				m[c] = cnt++;
			}
			v[m[c]].push_back(i);
		}
		re = 1;
		for (int i = 0; i < cnt; i++) {//每个数(离散化后的)的位置分别进行处理,尺取法
			int le = 0, rig = 0;
			while (le <= rig) {
				while (rig + 1 < v[i].size() && v[i][rig + 1] - v[i][le] + 1 - (rig + 1 - le + 1) <= k) {
					rig++;
				}
				re = max(re, rig - le + 1);
				le++;
			}
		}
		printf("%d\n", re);
	}
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值