k-Amazing Numbers(数学+思维)

题目来源

https://codeforces.com/contest/1417/problem/C

题目描述在这里插入图片描述

题目描述

给定一个序列,统计这个序列长度为1-n长度的连续子序列的分别公共最小值,不存在输出-1。

题解思路

首先统计相同的数在序列中的最大间隔,包括此数对序列头,序列尾的间隔(利用map记录此数字上一次出现的index下标即可)。此间隔就是能取到这个数字为贡献的最小序列长度。然后对于每个数字能做出贡献的最小代价长度进行更新,例如数字4,2都最小要长度3的子序列才可以取到,那么ans[3]就更新成最小的数字2。最后输出即可。(输出时注意当第一次 不为-1后,后面都要更新最小,因为假设长度为3的最小值为2。那后面的答案一定不会大于2)

题解代码

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <unordered_map>
using namespace std;
const int N=3*100010;
int ans[N],sz[N],st[N];
unordered_map<int,int>mp;
int main(void)
{
    int t;
    cin>>t;
    while(t--)
    {
        int n;
        cin>>n;
        mp.clear();
        memset(st,0,sizeof st);
        memset(ans,0x3f,sizeof ans);
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&sz[i]);
        }
        for(int i=1;i<=n;i++)//求取每个数的最大间隔(已经包括序列首)
        {
            int x=sz[i];
            st[x]=max(st[x],i-mp[x]);
            mp[x]=i;
        }
        for(int i=1;i<=n;i++)//处理序列尾 例如 2 2 3 4 5 (2到序列尾最小间隔为4)
        {
            int x=sz[i];
            st[sz[i]]=max(st[sz[i]],n+1-mp[sz[i]]);
        }
        for(int i=1;i<=n;i++)//对每个数字所归属的间隔长度,取最小的数字
        {
            int x=sz[i],p=st[x];
            ans[p]=min(ans[p],x);
        }
        int res=0x3f3f3f3f;
        int flag=1;
        for(int i=1;i<=n;i++)//输出答案
        {
            if(flag&&ans[i]==0x3f3f3f3f)printf("-1 ");
            else
            {
                flag=0;//第一次走出-1后,后面更新最小输出。
                if(ans[i]!=-1)res=min(res,ans[i]);
                printf("%d ",res);
            }
        }
        printf("\n");
    }
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值