【Codeforces Round 847】D. Matryoshkas

题目翻译

这个题的大致思路和下面这道题很相似P7260 [COCI2009-2010#3] RAZGOVOR - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

因此在题解【洛谷】 P7260 [COCI2009-2010#3] RAZGOVOR-CSDN博客中出现的思路不予重复,只分析一下如何将这个题转化为上述问题。

思路转换

这道题和PAZGOVER很像很像,但是这题目给出的所有数字所在的区间不一定是连续的。比如所有数字所在的区间可能是 [1, 5] , [15, 20],此种情况下,无法直接使用P7260的代码。

另外,对于此题的数据范围,不难发现玩具的数字大小为 1 ~ 1e^9,如果还使用数组来计数的话一定会爆栈。

不难想到,可以利用stl中map的特性,来完成此题:map可以对容器内部的数据按照first的大小进行排序,利用这个特性,我们就可以在nlogn的时间复杂度内得到有序的(位置,数量)二元组,之后需要解决的问题是二元组的不连续的问题。

我们指导,只有位置是连续的,才可以使用P7260的写法,所以现在需要将非连续的二元组转化为"连续"的二元组,这里可以利用map遍历扩充vector数组来实现,受空间限制,不能将每一个没有出现的数字都添加到vector数组当中,但对于一连串的未出现的0,可以用一个0来替代,这样的效果都是一样的。

AC代码

#include <bits/stdc++.h>

using namespace std;

const int N = 1e5 + 10, M = 2 * N;
const int mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;
const int hash_num = 131;
const double eps = 1e-6;
const double pi = acos(-1);
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int, int> PII;
typedef long double LD;

int n, m;
map<int, int> dic;
vector<PII> b(M);
int main()
{
	int t;
	scanf("%d", &t);
	while(t --)
	{
		dic.clear();
		b.clear();
		int n;
		scanf("%d", &n);
		for(int i = 1; i <= n; i ++)
		{
			int x;
			scanf("%d", &x);
			dic[x] ++;
		}
		b.push_back({0, 0});
		for(auto t : dic)
		{
			int x = t.first, y = t.second;
			if(x != b.back().first + 1) b.push_back({b.back().first + 1, 0});
			b.push_back(t);
		}
		LL cnt = 0;
		int tmp = 0;
		for(auto t : b)	
		{
			int tt = t.second;
			if(tt > tmp) cnt += tt - tmp;
			tmp = tt;
		}
		cout << cnt << endl;
	}
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值