目錄最後
牛客挑戰賽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開始隨機...