PouringWater (SRM 439 Div2 500)

PouringWater (SRM 439 Div2 500)

题目链接:http://www.topcoder.com/stat?c=problem_statement&pm=10408&rd=13747

最终的水要放在K个瓶子里面,而每个瓶子中的水的数量必须为2的整数幂,即最终的水数量n'要能分解成
k个2的整数幂,也就是new_n的二进制表示中1的个数要<=k.

用count(n)表示n的二进制表示中1的个数,如果count(n)<=k,那就不需要买瓶子了。
如果count(n)>k,说明我们要找到第一个n'使得n'>n并且count(n')<=k。那就是说我们要减少n中1的个数。
我们把n表示为x0ab.其中a为全1,b为全0. a,b的长度>=0.
很明显,第一个减少1的个数的n'应该为x1{(a+b)个0},也就是把ab全部变成0.ab前的0变为1.即加上一个1<<length(b).
因为对b来说,无论增加多少都会增加1的个数。
然后再判断n'的1的个数,直到count(n)<=k。
因为n最大为10^7,n'最大为10^8,int类型不会溢出。因此边界条件就无需判断了。

 1  #include  < vector >
 2  #include  < algorithm >
 3  #include  < sstream >
 4  #include  < string >
 5  #include  < iostream >
 6 
 7  using   namespace  std;
 8 
 9  int  count( int  i)
10  {
11       int  res  =   0 ;
12       while (i != 0 ){
13          i &= (i - 1 );
14          res ++ ;
15      }
16 
17       return  res;
18  }
19 
20            class  PouringWater
21                { 
22                 public
23                 int  getMinBottles( int  N,  int  K) 
24                    { 
25                         int  res  =   0 ;
26                         int  mask  =   1 ;
27 
28                         while (count(N) > K){

29                             // 找到第一个1 ...第n次犯了没把N&mask括号括起来的错误了。。。&的优先级<等号...
30                             while ( (N & mask) == 0 ) mask <<= 1 ;

31                           // 加上mask使得1的数目减少
32                            N += mask;
33                            res  +=  mask; 
34                        }
35 
36                         return  res;
37                    } 
38               
39 




你可能感兴趣的:(PouringWater (SRM 439 Div2 500))