4144: 优秀的拆分(power)

内存限制:128 MB 时间限制:1.000 S
评测方式:文本比较 命题人:
提交:8 解决:3

题目描述

一般来说,一个正整数可以拆分成若干个正整数的和。

例如,lns="http://www.w3.org/1998/Math/MathML">1=1lns="http://www.w3.org/1998/Math/MathML">10=1+2+3+4 等。对于正整数 lns="http://www.w3.org/1998/Math/MathML"> 的一种特定拆分,我们称它为“优秀的”,当且仅当在这种拆分下,lns="http://www.w3.org/1998/Math/MathML"> 被分解为了若干个不同的 lns="http://www.w3.org/1998/Math/MathML">2 的正整数次幂。注意,一个数 lns="http://www.w3.org/1998/Math/MathML"> 能被表示成 lns="http://www.w3.org/1998/Math/MathML">2 的正整数次幂,当且仅当 lns="http://www.w3.org/1998/Math/MathML"> 能通过正整数个 lns="http://www.w3.org/1998/Math/MathML">2 相乘在一起得到。

例如,lns="http://www.w3.org/1998/Math/MathML">10=8+2=23+21 是一个优秀的拆分。但是,lns="http://www.w3.org/1998/Math/MathML">7=4+2+1=22+21+20 就不是一个优秀的拆分,因为 lns="http://www.w3.org/1998/Math/MathML">1 不是 lns="http://www.w3.org/1998/Math/MathML">2 的正整数次幂。

现在,给定正整数 lns="http://www.w3.org/1998/Math/MathML">,你需要判断这个数的所有拆分中,是否存在优秀的拆分。若存在,请你给出具体的拆分方案。

输入

输入只有一行,一个整数 lns="http://www.w3.org/1998/Math/MathML">,代表需要判断的数。

输出

如果这个数的所有拆分中,存在优秀的拆分。那么,你需要从大到小输出这个拆分中的每一个数,相邻两个数之间用一个空格隔开。可以证明,在规定了拆分数字的顺序后,该拆分方案是唯一的。

若不存在优秀的拆分,输出 -1


样例输入 复制

6

样例输出 复制

4 2

提示

样例 1 解释

lns="http://www.w3.org/1998/Math/MathML">6=4+2=22+21 是一个优秀的拆分。注意,lns="http://www.w3.org/1998/Math/MathML">6=2+2+2 不是一个优秀的拆分,因为拆分成的 lns="http://www.w3.org/1998/Math/MathML">3 个数不满足每个数互不相同。

数据规模与约定

  • 对于 lns="http://www.w3.org/1998/Math/MathML">20% 的数据,lns="http://www.w3.org/1998/Math/MathML">10
  • 对于另外 lns="http://www.w3.org/1998/Math/MathML">20% 的数据,保证 lns="http://www.w3.org/1998/Math/MathML"> 为奇数。
  • 对于另外 lns="http://www.w3.org/1998/Math/MathML">20% 的数据,保证 lns="http://www.w3.org/1998/Math/MathML"> 为 lns="http://www.w3.org/1998/Math/MathML">2 的正整数次幂。
  • 对于 lns="http://www.w3.org/1998/Math/MathML">80% 的数据,lns="http://www.w3.org/1998/Math/MathML">1024
  • 对于 lns="http://www.w3.org/1998/Math/MathML">100% 的数据,lns="http://www.w3.org/1998/Math/MathML">1107
  • #include<bits/stdc++.h>
    using namespace std;
    /*
    定义:分解为了若干个不同的2的正整数次幂
    性质:是偶数,奇数不存在优秀的拆分
    思路:
    如果n是偶数,将n进行进制转换10->1010
    */
    int a[110],n,k=0; //k表示a数组的下标
    int main(){
        cin>>n; //特判奇数的情况
        if(n%2!=0){
            cout<<-1;
    	    return 0;
        }
        //进制转换
        int t=1; //表示2的次方
        while(n !=0){
    	    if(n %2 != 0){
                k++;
                a[k]= t;
            }
            t=t*2;
            n=n/2;
        }
        //逆序输出结果
        for(int i= k;i >= 1;i--){
            cout<<a[i]<<" ";
        }
        return 0;
    }

  • #include<bits/stdc++.h>
    using namespace std;
    
    int main() {
    	int n;cin>>n;
    	if(n%2==1) {
    		cout<<-1<<endl;
    		return 0;
    	}
    	int x=log2(n);
    	for(int i=x;i>=1;i--) {
    		if ((1<<i)<=n) {
    			cout<<(1<<i)<<" ";
    			n-=(1<<i);
    		}
    	}
    }