现在有n个货物,第i个货物的重量是 2^wi 。每次搬的时候要求货物重量的总和是一个2的幂。问最少要搬几次能把所有的货物搬完。
样例解释:
1,1,2作为一组。
3,3作为一组。
Input
单组测试数据。
第一行有一个整数n (1≤n≤10^6),表示有几个货物。
第二行有n个整数 w1,w2,…,wn,(0≤wi≤10^6)。
Output
输出最少的运货次数。
Input示例
5
1 1 2 3 3
思路:
2^2+2^2 = 2^3 = 2*(2^2)
通过这个例子我们可以发现,2的2次幂出现了两次可以合成一个2的3次幂,只有这种情况下才可以成为一个2的幂
所以如果某 i 次幂的个数>1,我们应该让它i+1次幂的个数加1,如果i次幂的个数是偶数(n)个,那么就可以合成的i+1次幂的个数就是n/2。如果某i次幂的个数==1,说明无法合成,就得这消耗一次去搬这个货物。
AC代码:
注意: 这个题可能会卡输入输出,然后如果不用输入输出外挂,这个代码耗时300+ms,用了输入输出外挂效率提高了10倍,耗时31ms。(第一次用输入输出外挂,就记录一下)
#include<bits/stdc++.h>
using namespace std;
const int maxn = 2e6+5;
int a[maxn];
int n;
int ans = 0;
//加速输入外挂(fread加强版)
const int MAXBUF = 10000;
char buf[MAXBUF], *ps = buf, *pe = buf+1;
inline void rnext()
{
if(++ps == pe)
pe = (ps = buf)+fread(buf,sizeof(char),sizeof(buf)/sizeof(char),stdin);
}
template <class T>
inline bool in(T &ans)
{
ans = 0;
T f = 1;
if(ps == pe) return false;//EOF
do{
rnext();
if('-' == *ps) f = -1;
}while(!isdigit(*ps) && ps != pe);
if(ps == pe) return false;//EOF
do
{
ans = (ans<<1)+(ans<<3)+*ps-48;
rnext();
}while(isdigit(*ps) && ps != pe);
ans *= f;
return true;
}
//加速输出外挂(fread加强版)
const int MAXOUT=10000;
char bufout[MAXOUT], outtmp[50],*pout = bufout, *pend = bufout+MAXOUT;
inline void write()
{
fwrite(bufout,sizeof(char),pout-bufout,stdout);
pout = bufout;
}
inline void out_char(char c){ *(pout++) = c;if(pout == pend) write();}
inline void out_str(char *s)
{
while(*s)
{
*(pout++) = *(s++);
if(pout == pend) write();
}
}
template <class T>
inline void out_int(T x) {
if(!x)
{
out_char('0');
return;
}
if(x < 0) x = -x,out_char('-');
int len = 0;
while(x)
{
outtmp[len++] = x%10+48;
x /= 10;
}
outtmp[len] = 0;
for(int i = 0, j = len-1; i < j; i++,j--) swap(outtmp[i],outtmp[j]);
out_str(outtmp);
}
//
int main()
{
#ifdef LOCAL
freopen("in.txt","r",stdin);
#endif // LOCAL
// ios_base::sync_with_stdio(false);
// cin.tie(NULL),cout.tie(NULL);
memset(a,0,sizeof(a));
int e;
in(n);
for(int i=1;i<=n;i++)
{
in(e);
a[e]++;
}
for(int i=0;i<=maxn-5;i++)
{
if(a[i]>1)
{
a[i+1] += a[i]/2;
a[i]%=2;
}
if(a[i] == 1) ans++;
}
out_int(ans);
write();
return 0;
}