牛客挑戰賽51 C NIT的數 回文數

2022-09-18 09:30:29 字數 2054 閱讀 5875

目錄最後

牛客挑戰賽51-c nit的數 #回文數#

給定乙個數\(x\),求滿足\(x\le y\),且\(y\)是回文數,這兩個條件中的第\(k\)小的\(y\)

\[1\le x\le 10^,1\le k\le 10^8,答案嚴格小於10^

\]如:

輸入1

14 1
輸出1

22
輸入2

99 2
輸出2

101
輸入2中,滿足條件的\(y\)有99 101 111 121...,第二小的是101

做出這題,你只要乙個oeis

關於回文

大概意思是:設\(a\)是乙個回文數,\(a\)在回文序列(注意包括0)的位置為f(a)

舉幾個例子你就知道怎麼求f(a)了:

都能明白了吧,具體的證明可以這樣想:123321是由123變出來的,而123前面還有123個數,可以變成11,22...122 221_ , 1_1 , 2_2 , 3_3, ... , 97_79 ,98_89 , 99_99,前者與1,2,3,...,122一一對應,共122個數,後者與0,1,2,3,...99一一對應,但是乙個'_'中可以填0~9任何乙個數,所以後者一共可以生成\(100\times 10=1000\)個回文數.所以123321前面共有\(122+1000=1122\)個數,排名就是\(1\ 123\)

如果回文數的長度為奇數,也同理

根據排名,我們也可以反推出原回文數(如果原回文數的長度為偶數,排名的最高位一定是\(1\),次高位一定不為0,否則,排名的最高位可能是\(1\)~\(9\),當最高位為\(1\)時,次高位一定是\(0\))

回到題目,就顯得簡單多了,我們二分找出大於等於\(x\)的最小回文數的排名,排名加上\(k\)後找到對應的回文數輸出即可

#include #include #define ll long long

#define int long long

using namespace std;

int getlen(ll x)

return cnt;

}ll pow10[15];

ll getranking(ll x)

ll getnum(ll rank)

else if(rank / pow10[len - 1] == 1) else

}signed main()

if(num < x)

l = mid;

else

r = mid - 1; }

cout << getnum(l + k);

return 0;

}

#include #include #define int long long

using namespace std;

int read()

int reverse(int x)

return tmp;

}signed main()

} }return 0;

}

#include #define ll long long

using namespace std;

int random(int r , int l = 1)

int main()

這個做法的複雜度大概是\(\log^2\)(二分加上求位數),儘管不是最優解,但相關回文數的知識還是挺重要的

牛客挑戰賽58

前i 1的二進位制相等,a的前n個數的前i 1位可以亂取,b的前n 1個數前i 1位也可以亂取,因為b的第n個數的前i 1異或可為任意值,所以sum1 2 i 1 n 2 i 1 n 1 2 i 1 2n 1 a的第i位為1且b的第i位為0 只要a的n數第i位中有乙個不為0的,a的第i位不為0,b的...

牛客Wannafly挑戰賽12 題解

傳送門 說是比賽題解,其實我只會前三題 後面的一定補 t1題意,在乙個長度為n的時間內,問如何選擇存款期限,使得收益最大。dp include include include include using namespace std define fi first define se second d...

日常摸魚 牛客挑戰賽3

無 期望dp,要用字首和優化一下。略了 比較水的追及問題。但是兩個點一開始就在一起要特判掉。稍微轉化一下。只用求數列中任意兩對數的和的位數,這個可以隨便套資料結構。思路大致跟上一場蝴蝶差不多。而且比上場那個簡單多了,連資料結構都不用套。給定乙個n個點的樹,以1為根,邊權都是1。乙個人從起點s開始隨機...