您的位置:首页 > 其它

2018.02.05【GDOI2018】模拟C组——Multiset

2018-02-06 21:29 309 查看

Description

Alice 正在玩一个 multiset。最初,集合中只有一个元素 0。每一轮,集合中的每一个元素 x 都有 3 种可能的操作:

1、x 加上 1.即 x = x +1。

2、x 分裂成两个非负整数 y, z。即 x = y + z, 且 y >=0, z >= 0。

3、什么都不做。

注意,在一轮中每个元素只能选择一种操作。

Alice 已经玩了很久了, 但她并不知道自己已经玩了多少轮。 现在给出最终的集合,请你输出 Alice 最少玩的轮数。

Input

第一行为一个整数N,描述最终集合的大小。

第二行为N个非负整数,为最终集合的每一个元素。

Output

输出唯一一行,Alice 最少玩的轮数。

Sample Input

Sample Input 1

1

0

Sample Input 2

4

1 1 1 1

Sample Input 3

5

0 3 0 3 0

Sample Output

Sample Output 1

0

Sample Output 2

3

Sample Output 3

5

Data Constraint

对于 10%的数据,N <= 10,A[i] <= 10

对于 30%的数据,N <= 50,A[i] <= 100

对于 50%的数据,N <= 1000,A[i] <= 10,000

对于 100%的数据,N <= 1,000,000,A[i] <= 1,000,000

思路

经过大佬讲解后,发现这是一道模拟题,不过比较麻烦。

程序

var
n,s,i,k,ans:longint;
a:array[0..1000001]of longint;
begin
readln(n);
for i:=1 to n do
begin
read(k);
inc(a[k]);
if ans<k then ans:=k;
end;
readln;
s:=a[0];
for i:=1 to ans do
s:=((s+1) shr 1)+a[i];
while s>1 do
begin
s:=(s+1)shr 1;
inc(ans);
end;
writeln(ans);
end.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: