洛谷 P7071 優秀的拆分 菜鳥題解

2021-10-10 09:44:58 字數 1721 閱讀 5032

有志者,事竟成,破釜沉舟,百二秦關終屬楚。

苦心人,天不負,臥薪嘗膽,三千越甲可吞吳。

首先可以明確,任何乙個整數都是可以用二進位制表示的;

那麼也就說任何乙個數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 ...