hiho209 Powers of Two

hiho209 Powers of Two

        时间限制: 10000ms
        单点时限: 1000ms
        内存限制: 256MB

描述

Given a positive integer N, it is possible to represent N as the sum of several positive or negative powers of 2 (± 2k for some k). For example 7 can be represented as 22 + 21 + 20 and 23 + (-20).

Your task is to find the representation which contains the minimum powers of 2.

输入

One positive integer N.  

For 80% of the data: 1 <= N <= 100000  

For 100% of the data: 1 <= N <= 2000000000

输出

The minimum number of powers of 2.

样例输入
7
样例输出
2



题意分析:

    给你一个数字n,比如7,7可以描述为2^2+2^1+2^0我们是知道的,但我们现在也可以将之描述为2^3-2^1,

前一种方法用了3个描述7这个数字,而后一种只用了两个,我们就是要找到能描述出n的最少数字个数.


思路:

    通过n的二进制码动手,我们可以发觉之所以我们能用更少的2幂次数来描述一个数是因为我们普遍的采用了一种方法:

    比如数字1265的二进制如下

                1  0  0  1  1  1  1  0  0  0  1

                1  0  1  0  0  0 -1  0  0  0  1

    像出现上图红色部分这种连续的1时,我们可以将红色部分转为下方的形式(-1即表示减去这个位置的位权),这样就完成了如下转化:    2^11+2^8+2^7+2^6+2^5+2^0   ->   2^11+2^9-2^5+2^0

    描述所需数字从6个降低到了4个,这就是核心思维.

实现时的小细节:

    设计为仅位移到0的位置时进行判断是否执行收缩(收缩指的就是上面所介绍的那种缩短方法),为1时只是记录1的数目加1;因为这个设计由0触发,故而对应7的二进制,我们应该理解为0111而不是111;最后的0用于触发收尾.

ac代码:

#include <stdio.h>

int mycal(int n){ 
	int ans,k; 
	ans=k=0; 
	do{
		k+=n&1;   //记录当前位置前方连续的1的数目
		n>>=1;
		if(!(n&1)){ 
			if(n&2){  
				if(k>1){//执行收缩
					ans+=1;
					k=1;
				}
				else if(k==1){ //不收缩
					ans+=1;
					k=0;
				}
			}else{
				if(k>1){//执行收缩
					ans+=2;
					k=0;
				}
				else if(k==1){ //不收缩
					ans+=1;
					k=0;
				}
			}
		}
	}while(n);
	return ans; 
}

int main(){
	int n;
	scanf("%d",&n);
	printf("%d",mycal(n));
	return 0;
}

			

猜你喜欢

转载自blog.csdn.net/qq_31964727/article/details/80898664