这里有n个重物,第i个重物的重量是2^{w_i}。她们每天任务要完成的重量是n个重物的重量和。
每次举重的重量和必须是2的幂,重物数量不要求。
但是为了方便,要使举重的次数最少。
输入
多组数据。 每组数据第一行一个整数n。(1 <= n <= 10^6) 第二行有n个整数w_1,w_2,…,w_n。(0 <= w_i <= 1000000)
输出
输出最少的举重次数。
样例输入
5
1 1 2 3 3
样例输出
2
提示
1,1,2一组;
3,3一组。
注意多组输入。
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int s[1000030];
int main()
{
int n, x;
while (scanf("%d", &n) != EOF)
{
memset(s, 0, sizeof(s));//数据初始化为0;
while (n--)
{
scanf("%d", &x);
s[x]++;//记录每个不同重量的重物出现次数;
}
for (int i = 0; i <= 1000029; i++)//遍历一下,因为不知道多大,所以开在给定w_i最大值之外;
{
if (s[i] > 1)
{
int x = s[i];//记录一下当前重物;
s[i] = 0;
if (x % 2 != 0) s[i] = 1;//判断是不是2的幂,不是,就将其附为1,表示一种情况;
int y = x / 2;
s[i + 1] += y;
}
}
int ans = 0;
for (int i = 0; i <= 1000029; i++)
{
if (s[i] != 0) ans++;
}
printf("%d\n", ans);
}
return 0;
}
int x = s[i];//记录一下当前重物;
s[i] = 0;
if (x % 2 != 0) s[i] = 1;//判断是不是2的幂,不是,就将其附为1,表示一种情况;
int y = x / 2;
s[i + 1] += y;
这段代码有点看不懂,希望看懂的可以告诉我一下为何这样。
还用另一种方法,用C++里面的set来做
#include<cstdio>
#include<algorithm>
#include<set>
using namespace std;
set<int> s;
int main()
{
int n, x;
while (~scanf("%d", &n))
{
s.clear();
while (n--)
{
scanf("%d", &x);
while (s.find(x) != s.end())//循环找
{
s.erase(x);
x++;//合并比如1 1合并一起就为2.题目要求的重量为2 的幂,所以可以这样合并。
}
s.insert(x);
}
printf("%d\n", s.size());
}
return 0;
}