[HNOI 2006] 鬼谷子的钱袋

BZOJ 1192
Luogu2320

运用了“分治”的思想,先选择\(n/2\),然后将问题转化为\([1,n/2]\)范围内的子问题,以此类推

一开始以为是将 n 的二进制表示中所有是 1 的拿出来,比如这样:

#include <cstdio>
#include <iostream>
using namespace std;
int main(){
    int n;
    cin>>n;
    int cnt=0;
    for(int i=0;(1<<i)<=n;i++) if((1<<i) & n) cnt++;
    printf("%d\n",cnt);
    for(int i=0;(1<<i)<=n;i++) if((1<<i)&n) printf("%d ",1<<i); 
    return 0;
}

但是其实并非如此,比如当 n=100 时,n 的二进制表示为 1100100 ,于是 1 并不在解中,然而如果没有 1 ,那么所有的奇数都无法被拼成。

BZOJ 上只要求输出个数,而洛谷上还要输出解的方案

#include <iostream>
using namespace std;
int main()
{
    int n,a[31];
    cin>>n;
    int cnt=0;
    while(n){
        a[++cnt]=(n&1?(n>>1)+1:n>>1);
        n>>=1;
    }
    cout<<cnt<<endl;
    for(int i=cnt;i>=1;i--) cout<<a[i]<<" "; 
    return 0;
}
posted @ 2018-10-19 18:08  昤昽  阅读(120)  评论(0编辑  收藏  举报