蓝桥杯2022年第十三届省赛真题-重复的数

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

solution1(通过40%)

#include<iostream>
#include<map>
using namespace std;
int main(){
    int n, m, a[100010], l, r, k, count;
    scanf("%d", &n);
    for(int i = 1; i <= n; i++)
        scanf("%d", a + i);
    scanf("%d", &m);
    while(m--){
        map<int, int> mp;
        count = 0;
        scanf("%d%d%d", &l, &r, &k);
        for(int i = l; i <= r; i++)
            mp[a[i]]++;
        for(map<int, int>::iterator it = mp.begin(); it != mp.end(); it++){
            if(it -> second == k) count++;
        }
        printf("%d\n", count);
    }
    return 0;
}

solution2

莫队 算法只适用于不要求 强制在线的情况

#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;

const int maxn = 1e5 + 10;
struct query{
	int l, r, id, k;
}q[maxn];
int a[maxn];//存储原始数据、
int p[maxn];//p[i]存储第i个元素的块号
int cnt[maxn];//cnt[i]第i个元素的出现次数
int kn[maxn];//kn[i]存储恰好出现i次数的个数
int ans[maxn];//ans[i]第i次查询的答案 

bool cmp(query q1, query q2){//先比较是否同块,不同则优先按照块号排序,相同则按照右边界r排序
	return p[q1.l] == p[q2.l] ? q1.r < q2.r : p[q1.l] < p[q2.l];
}

void add(int pos){//增加元素
	kn[cnt[a[pos]]]--;//记元素值a[pos]的出现次数为N,则出现N次的元素个数减一
	cnt[a[pos]]++;//元素值a[pos]的出现次数更新为N+1
	kn[cnt[a[pos]]]++;//出现N+1次的元素个数加一
}

void del(int pos){//移除元素
	kn[cnt[a[pos]]]--;//出现N次的元素个数减一
	cnt[a[pos]]--;//元素值a[pos]的出现次数更新为N-1
	kn[cnt[a[pos]]]++;//出现N-1次的元素个数加一
}
 
int main(){
	int n, m, b, l = 1, r = 0;
	scanf("%d", &n);
	b = sqrt(n);
	for(int i = 1; i <= n; i++){
		scanf("%d", a + i);
		p[i] = (i - 1) / b + 1;//计算每个元素的所属块号
	}
	scanf("%d", &m);
	for(int i = 1; i <= m; i++){
		cin >> q[i].l >> q[i].r >> q[i].k;//用scanf()输入会有三个测试点运行错误
		q[i].id = i;//记录查询编号
	}
	sort(q + 1, q + 1 + m, cmp);
	for(int i = 1; i <= m; i++){//处理查询 
		while(l < q[i].l) del(l++);//删除[l, q[i].l - 1]区间内的元素
		while(r > q[i].r) del(r--);//删除区间[q[i].r + 1, r]内的元素
		while(l > q[i].l) add(--l);//增加区间[q[i].l, l-1]内的元素
		while(r < q[i].r) add(++r);//增加区间[r+1, q[i].r]内的元素
		ans[q[i].id] = kn[q[i].k]; //记录本区间的查询结果
	}
	for(int i = 1; i <= m; i++)
		printf("%d\n", ans[i]);
	return 0;
}
  • 17
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值