洛谷 P5657 格雷碼

2022-06-01 10:57:08 字數 1137 閱讀 1580

思路:此題是由乙個序列通過n次轉換得來的,因此我們可以把這個序列還原回去,在還原的過程中得到問題的解。

做法:設第乙個格雷碼的編號是0,第2個是1……題目中所求的是編號為m(題目中的k)的n位格雷碼,通過觀察發現這個格雷碼序列的前半段的首位都是0,而後半段都是1。所以我們可以通過判斷當前m是在前半段還是在後半段來判斷出n位編號為m的格雷碼的首位是什麼,同時我們也可以找出這個格雷碼是屬於哪個區間了。確定當前區間後,我們可以繼續通過以下方法繼續確定他所在的區間以及當前這個n位格雷碼的編號為m的第i個數是多少,直到把這整個區間縮成乙個數為止(用二分來實現)。但是我們需要注意,當確定當前區間後想要找下一位時,其中的順序不一定是首位為0的在前,首位為1的在後(將上一次確定的區間裡所有數的首位都去掉後),但我們依然可以發現乙個規律,就是當當前的m在前半段時,下一位所確定的區間一定是0在前,1在後;反之則一定是1在前,0在後。注意如果此時的m在後半段,那麼m要減去區間的一半

觀察樣例 :

2 3

我們得到2位格雷碼有四個 :

00

0111

10

然後我們找編號為3的格雷碼在後半段(編號從0開始的),因此確定第一位為1,輸出1,將m - 序列的長度 / 2(因為資料太大,所以**中是將長度一開始設定為2的n - 1次方了,然後減的直接就是序列的長度,但是意義上和 - 長度 / 2相等),此時的m為1;因為剛剛m在後半段,所以順序為先1再0,因為此時的m在後半段,所以輸出0

**

1 #include 2

#define inf 0x3f3f3f3f

3#define int unsigned long long//

unsigned long long了解一下

4using

namespace

std;

5int

n, m, l, f;

6signed main()719

else

//前半段

2024 l >>= 1;//

二分 25}26

return0;

27 }

洛谷 P5657 CSP S2019 格雷碼

p5657 分析 簽到題,不過也有不少細節。資料範圍需要開unsigned long long,前年也有很多人因此丟了5分。pow會出現神必錯誤,需要手寫乙個mpow函式。演算法 我是記錄當前的 l,r 判斷 k 與 mid 的大小,然後分類討論倒序和正序時選左邊和選右邊手玩的結論。變數 f 代表順...

洛谷P3965 迴圈格 費用流

乙個完美的迴圈格是這樣定義的 對於任意乙個起始位置,你都可以沿著箭頭最終回到起始位置。如果乙個迴圈格不滿足完美,你可以隨意修改任意乙個元素的箭頭直到完美。例如下圖,左邊不是乙個完美的迴圈格,因為只有從 1,1 1,2 2,0 2,3 1,1 1,2 2,0 2,3 1,1 1,2 2 0 2,3 出...

洛谷 P2145 JSOI2007 祖碼

一道特別毒瘤的題,好像目前沒有完全的正解,只有乙個比較優的解法 f i j 表示從i j所用的最小數量.首先,去重,就是將所有連續的相同的點縮成乙個點,sum i 表示縮點後新圖第i個位置有幾個點.如果g i g j 加起來的數量大於等於三 sum i sum j 3 則f i j f i 1 j ...