$CF546B Soldier and Badges$
[$ CF546B \ Soldier \ and \ Badges\(](https://www.luogu.org/problem/CF546B) 这道题看到许多大佬使用了```sort```,十分高端,本蒟蒻表示\)%%%\(,但是,我们还可以用一种更快也更容易想到的方法解决这道题。所以,本题解就来介绍这种方法来\)A$了这道题。
本题解使用的这种方法的思想可以被近似的看成桶排序,我们建一个数组为原数组,就是要输入的数组,不妨设为\(a[]\),因为题目中的数据要求是\((1 \leq n \leq 3000)\),所以,\(a[]\)数组大小应该是\(a[3005]\),再设一个类似于桶的数组,即\(flag[]\),\(flag\)数组的作用是统计某个数出现的次数,题目又规定\((1 \leq a_i \leq n)\),所以,注意了, 注意了, 注意了, 这里\(flag\)数组的大小应设为\(n\)的\(2\)倍,为什么呢?应为\(flag\)数组的作用是统计某个数出现的次数,而题目又规定每进行一次操作可以将一个数\(+1\),而我们考虑最差的情况,就是\(n\)为最大,即\(3000\),而每一个数\(a_i\)又都是跟\(n\)一样的,此时,数\(a_i\)最大为\(6000\),所以,\(flag\)数组应成跟\(n \times 2\)这么大,即开成\(flag[6001]\)。
至于代码实现十分简单,如下:
int n,flag[6001],a[6001]; //a[]是要输入的数组,flag[]为桶
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i]; //输入
flag[a[i]]++; //桶中每个元素出现的次数++
}
好了,就此,我们把数据存储的问题解决了,接下来,我们再来实际解决问题。\((QAQ)\)。
其实本题通过简单的枚举就可以做出来了,枚举的范围应该为\(n \times 2\),至于原因前文已经阐述过了,原因和前面一样,为了考虑最差的情况吗。其他解释都在\(code\)里,自己慢慢查看\(qwq\),(其中\(sum\)的含义是要进行几次操作)
for(int i=1;i<=n*2;i++) //开始枚举
{
if(flag[i]>1) //又两个及以上元素
{
flag[i+1]+=(flag[i]-1);//多了几个数就下一个桶就加几
sum+=(flag[i]-1); //多了几个数就要进行几次操作
flag[i]=1; //清除多余的次数
}
}
好了,本题解就告一段落,希望读者明白了该算法的含义并会灵活运用,下面给出完整代码:
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n,flag[6001],a[6001],sum=0;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
flag[a[i]]++;
}
for(int i=1;i<=n*2;i++)
{
if(flag[i]>1)
{
flag[i+1]+=(flag[i]-1);
sum+=(flag[i]-1);
flag[i]=1;
}
}
cout<<sum;
return 0;
}

浙公网安备 33010602011771号