codeforce 457DIV2 B题

  题意:
  题目给出两个整数n,k,(n<=10^18,k<=10^5),求一个含有k个整数的序列,要求以2为底,以序列内数字为幂的和为n,其中序列内最大的数最小,若有多个序列满足条件,输出字典序最大的一个。

样例:input :23 5 output:Yes  3 3 2 1 0  ,其中2^3+2^3+2^2+2^1+2^0=23=n

分析

两个点:1:2^n=2*2^n-1,也就是说答案序列中任何一个数x都可以变为两个x-1
           2: 结合二进制化十进制的方法,可以得到用2的幂次方表示的n

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <iostream>
 5 #include <map>
 6 using namespace std;
 7 long long n;
 8 int k;
 9 map<int,int>b;
10 int main(){
11     cin>>n>>k;
12     int m=0;
13     while(n){
14         b[m]=n&1;
15         n/=2;
16         if(b[m++])k--;
17     }
18     if(k<0){
19         printf("No");
20         return 0;
21     }
22     m--;
23     int i;
24     for(i=m;;i--){//使最大值最小
25         if(b[i]>k)break;
26         b[i-1]+=2*b[i];
27         k-=b[i];
28         b[i]=0;
29     }
30     int j;
31     for(j=min(0,i);j<=i;j++)if(b[j])break;
32     for(;;j--){
33         if(!k)break;
34         if(b[j]){
35         b[j]--;
36         b[j-1]+=2;
37         k--;}
38     }
39     printf("Yes\n");
40     for(int ll=m;ll>=j;ll--)
41         for(int l=1;l<=b[ll];l++)printf("%d ",ll);
42 return 0;
43 }
View Code

 

posted @ 2018-04-14 00:30  蒟蒻LQL  阅读(229)  评论(0编辑  收藏  举报