补题

困困,今天勉强写个补题的博客吧!因为发现思考一遍距离可以写出来仍然有很大一个差距……咳咳咳,就是我太懒才拖到了现在!!

(1)Elephant And Array(枚举)

题目链接: CodeForces - 221D

题意:给你一个序列,给定一个区间,问在这个区间中有哪些数字出现了它的数值那么多次。

思路(莫队不会呐!!):用数组存储b[数值]=出现次数,注意如果只有n个数,那么如果出现其数值大于n的m,就它绝对不可能出现m次!(最多n个数哇)。

第一次循环,先找到出现次数多于数值本身的(例如b[4]=6),以这个数值为基础,再遍历一次序列,标记出在每一个位置这个数值出现的次数。遍历完一遍之后,对于每个问题,看看这个数字是否符合要求(利用前缀和,比如在l处已经出现了2次,在r处总计已经出现了5次,那么在[l,r]中,就出现了5-2=3次,如果恰好等于此时的数字i=4,那么符合要求),ans[j]++;(j是循环的题目)。

代码:

#include<iostream>
#include<cstring>
using namespace std;
int n,m,ans[10000],a[10000],b[10000],sum[10000];//忘了该开多大空间
int l[10000],r[10000];
int main()
{
    cin>>n>>m;
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
        if(a[i]<=n)
        {
            b[a[i]]++;
        }
    }
    for(int i=1;i<=m;i++)
    cin>>l[i]>>r[i];
    for(int i=1;i<=n;i++)
    {
        if(b[i]>=i)
        {
            for(int j=1;j<=n;j++)
            {
                if(a[j]==i)
                    sum[j]=sum[j-1]+1;
                else
                    sum[j]=sum[j-1];
            }
            for(int j=1;j<=m;j++)
            {
                if(sum[r[j]]-sum[l[j]-1]==i)//l这部分的减1可能会忘掉,不减1的话最左边如果也有一个数字就不会被算上
                    ans[j]++;
            }
        }
    }
    for(int i=1;i<=m;i++)
    {
        cout<<ans[i]<<endl;
    }
}

 (2)Array(枚举)

题目链接:CodeForces - 224B

题意:给定一个序列a,求一个序列,使这个序列中恰好有k个不同的数,数列可以不是最短的(我喜欢最短!!)。

思路:枚举,从前往后找,找到k个不同的元素,标记这里的位置,然后从这里往前,也是找k个不同的元素(第一遍最左边要是第一个元素相同了好几个,就可以通过这里来消去相同的)。

代码

#include<iostream>
#include<cstring>
#include<set>
using namespace std;
int main()
{
    int n,k,a[10000];
    int be,en;
    int flag=0,flag2=0;
    set<int> s;
    cin>>n>>k;
    for(int i=1;i<=n;i++) cin>>a[i];
    for(int i=1;i<=n;i++)
    {
        s.insert(a[i]);
        if(s.size()==k)
        {
            flag=1;
            en=i;
            break;
        }
    }
    s.clear();
    for(int j=en;j>=1;j--)
    {
        s.insert(a[j]);
        if(s.size()==k)
        {
            flag2=1;
            be=j;
            break;
        }
    }
    if(flag==1&&flag2==1)
        cout<<be<<" "<<en<<endl;
    else cout<<"-1 -1"<<endl;
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值