有志者,事竟成,破釜沉舟,百二秦關終屬楚。苦心人,天不負,臥薪嘗膽,三千越甲可吞吳。
首先可以明確,任何乙個整數都是可以用二進位制表示的;
那麼也就說任何乙個數num都是可以用num
=∑i=
0n×a
inum = \sum_^n × a_i
num=∑i
=0n
×ai
來表示的,其中n
nn代表num
numnu
m二進位制的位數,a
ia_i
ai代表二進位制第i
ii位上的數。
題目中說2的正整數次冪,也就是說,不包括2
02^0
20,在二進位制中表示num
numnu
m & 111!
=1!= 1
!=1。第二個問題解決。
這個問題其實本來就不存在的,比如說乙個數是4
44,他的二進位制就是100
10010
0,可以分解為2
22^2
22,另外乙個數是6,二進位制是110
11011
0,可以分解為22+
212^2 + 2^1
22+2
1,因為二進位制的緣故,只需要按位分解就好,並不需要做判重操作
以上這些說完,其實思路已經就有了,輸入為nnn:
然後我首先判斷它是不是奇數,如果是奇數,不滿足要求,直接輸出-1;
然後開始迴圈,宣告vector< int > v,以及乙個記錄移位操作的變數int p,每次n >>= 1左移一位,相應的每次p <<= 1右移一位,因為需要記錄當前n二進位制這一位如果為1,它對應的十進位制是多少,然後把當前大小的p存入陣列v中;
最後根據題目要求,把v逆序輸出就好了。
一點點輸出時候的小技巧:#include
using
namespace std;
intmain()
vector<
int> v;
int p =1;
for(
; n !=
0; n >>=
1, p <<=1)
if(n &
1) v.
push_back
(p);
for(
int i = v.
size()
-1; i >=
0; i--
) cout << v[i]
<<
((i ==0)
?'\n'
:' ');
return0;
}
一般適用於非最後乙個元素之後輸出空格,最後乙個元素之後輸出換行符。
用三元表示式判斷一下就好了,用習慣了還是挺順手的。
for
(int i =
0, sz = v.
size()
; i < sz; i++
)printf
("%d%c"
, v[i]
,(i == sz -1)
?'\n'
:' '
);
字串hash 洛谷P1117 優秀的拆分
這裡講一95分的演算法 就是用字串hash取搞 怎麼弄呢?我們列舉aa 所有的aa 用字串hash取判斷a和a是否相同 然後記錄aa的開頭位置和結尾位置 然後乘法原理統計答案就好了 include define pow define ll long long using namespace std ...
洛谷 P2404 自然數的拆分問題
任何乙個大於1的自然數n,總可以拆分成若干個小於n的自然數之和。任何乙個大於1的自然數n,總可以拆分成若干個小於n的自然數之和。輸入格式 輸入 待拆分的自然數n。輸出格式 輸出 若干數的加法式子。輸入樣例 1 複製 7 輸出樣例 1 複製 1 1 1 1 1 1 1 1 1 1 1 1 2 1 1 ...
洛谷 P1755 斐波那契的拆分
無已知任意乙個正整數都可以拆分為若干個斐波納契數,現在,讓你求出n的拆分方法 輸入格式 乙個數t,表示有t組資料 接下來t行,每行乙個數n 如題 輸出格式 t行,每行乙個字串,表示拆分方法 格式 n a1 a2 a3 an 要求從小到大輸出 輸入樣例 1 複製 input1 1 1input2 1 ...