时间:1s 空间:256M
目录
题目描述:
小信有很多组卡牌,每组卡牌的形式像这样,,是这组卡牌的第一张数值,是这组卡牌的长度。
但有一天他不小心把所有卡牌搞混在了一起。比如他一开始有两组卡牌和,混在一起之后变成了。
给定搞混后的卡牌,问你小信最初最少有多少组卡牌。
输入格式:
第一行包含一个整数,表示测试数据组数。
对于每组测试数据,第一行一个整数,代表所有卡牌混在一起后的总长度。
第二行个整数,,代表混合后的卡牌序列。
输出格式:
对于每组测试数据,输出一个整数表示最初最少有多少组卡牌。
样例1输入:
10
6
2 2 3 4 3 1
5
11 8 7 10 9
6
1000000000 1000000000 1000000000 1000000000 1000000000 1000000000
8
1 1 4 4 2 3 2 3
6
1 2 3 2 3 4
7
10 11 11 12 12 13 13
7
8 8 9 9 10 10 11
8
4 14 5 15 6 16 7 17
8
5 15 6 14 8 12 9 11
5
4 2 2 3 4
样例1输出:
2
1
6
2
2
2
2
2
4
3
约定与提示:
对于100%的数据,
,
,
。
保证每组测试数据中的加起来的总和不超过。
主要思路:
我们会发现这可以贪心,因为如果把一个可以分到这个组里的却不分到这个组,那一定是分的组数是只多不少的。
我们可以用1个map来存储,第一个关键词是每一张卡牌上的数值,第二关键词是这张卡牌有几张?
vector<int> x(n+1);
map<int,int>mp;
for(int i=1;i<=n;i++)
{
cin>>x[i];
mp[x[i]]++;
}
注:map是有一个元素就分配一个空间,空间可以不连续,所以不会爆空间。
接着,我们sort一下x(x也可以是数组),for一遍1到n每次取出这一个x[i],如果这个x[i]也就是这张牌没有了,那么就continue,否则就一直向后找比自己大1的,将那张牌数量-1。分好后答案++。
sort(x.begin()+1,x.end());
for(int i=1;i<=n;i++)
{
int num=x[i];
if(!mp[num])
{
continue;
}
while(mp[num])
{
mp[num]--;
num++;
}
cnt++;
}
最后上整体代码:
#include<bits/stdc++.h>
using namespace std;
int main()
{
int t;
cin>>t;
while(t--)
{
int n;
cin>>n;
vector<int> x(n+1);
map<int,int>mp;
for(int i=1;i<=n;i++)
{
cin>>x[i];
mp[x[i]]++;
}
sort(x.begin()+1,x.end());
int cnt=0;
for(int i=1;i<=n;i++)
{
int num=x[i];
if(!mp[num])
{
continue;
}
while(mp[num])
{
mp[num]--;
num++;
}
cnt++;
}
cout<<cnt<<'\n';
}
return 0;
}