第O题 巧用二进制解答 现在有n个货物,第i个货物的重量是。。。

现在有n个货物,第i个货物的重量是 2wi2wi 。每次搬的时候要求货物重量的总和是一个2的幂。问最少要搬几次能把所有的货物搬完。

样例解释:

1,1,2作为一组。

3,3作为一组。

Input

单组测试数据。 
第一行有一个整数n (1≤n≤10^6),表示有几个货物。 
第二行有n个整数 w1,w2,...,wn,(0≤wi≤10^6)。

Output

输出最少的运货次数。

Sample Input

样例输入1
5
1 1 2 3 3

Sample Output

样例输出1
2

上解题思路

:2的b进制 b=1.2.3.4.5.6.。。。。等

     相当于 十进制10 100 1000 10000.。、、找规律,第b+1个0为1

则以此类推 

3的b进制 b=1.2.3.4.5.6

相当于 三进制10 100 1000 10000·······

  则如上题即为求10+10+100+1000+1000的二进制数中1的个数!!

 等于11000,其中两个1所以为两个

附代码:C++

#include<stdio.h>
#include<string.h>
#define maxn 1000100
int arr[maxn]; 
int main()
{
	int n,x;
	while(scanf("%d",&n)!=EOF)
	{
		memset(arr,0,sizeof(arr)); 
		while(n--)
		{
			scanf("%d",&x);
            arr[x]++; 
		} 
		int sum=0;
		for(int i=0;i<maxn;++i)
		{
			if(arr[i]>1)
			{
				arr[i+1]+=arr[i]/2;
				arr[i]%=2; 
			} 
			if(arr[i]==1)
				++sum; 
		} 
		printf("%d\n",sum); 
	} 
	return 0;
}

因为没有学完io流java的代码优化的不够,超时了

不过思路一样 不清楚上述思路的也可参考

JAVA:超时!!

import java.util.Scanner;

public class Main {
	public static void main(String []ages)
	  {
		  Scanner sc=new Scanner(System.in);
		  int n=sc.nextInt();
		  int arr[]=new int [1001000];
		  int sum=0;	
		while(n--!=0)
		  {
			   int a=sc.nextInt();
			   arr[a]++;
		  }
			 
		 for(int i=0;i<=1000010;i++)
		 {
			 if(arr[i]>1)
			 {
	             arr[i+1]+=arr[i]/2;
	             arr[i]%=2;
			 }
			 if(arr[i]==1)
			 {
				 sum++;
			 }
		 }
		 System.out.print(sum);
	  }
}

大体思路为数组操作简单的就不说了

猜你喜欢

转载自blog.csdn.net/lioncatch/article/details/81104668