小白进阶之路-CodeForces - 616D

链接:https://codeforces.ml/problemset/problem/616/D

题意:寻找最长字串,使得子串中不同数字的个数不超过 K 。

 

Solution:尺取法,用数组vis[]存储当前字串各数字个数,num用来存储当前字串中不同数字个数,外层循环保证右边界到达n处,当当前字串不停数字个数大于 K 时,左下标开始向右移动,每次维护当前最长字串的左右下标。

 

思路错误之处:想用map记录当前字串中各数字的个数,但无奈不熟悉map中size的存储方式。。。。没看数据范围,弱鸡了。。。

 

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cmath>
#include<stack>
#include<queue>
#include<map> 
#include<list>
#include<string>
#include<cstring>
#include<set>
#include<vector>
#define ll long long
#define memset(a,n) memset(a,n,sizeof(a))
#define mp make_pair 
#define pb push_back
using namespace std;
const int maxn = 1e6 + 100;

int n,k;
int vis[maxn],a[maxn];

int main()
{
    scanf("%d%d",&n,&k);memset(vis,0);
    for(int i  = 1;i <= n;i++) scanf("%d",&a[i]);
    int L = 1,R = 1; // 尺取左右下标
    int l = 1,r = 1;int num = 0; // num当前字串中不同数字的个数
    for(;R <= n;R++){
        vis[a[R]]++;
        if(vis[a[R]] == 1) num++;
        while(num > k){
            vis[a[L]]--;
            if(vis[a[L]] == 0) num--;
            L++;
        }
        if(R - L > r - l){
            r = R;l = L;
        }
    }
    printf("%d %d\n",l,r);
    return 0;
}

 

posted @ 2020-05-04 18:15  Wise_4  阅读(200)  评论(0编辑  收藏  举报