1. 程式人生 > >【zhx】endless【解題報告】

【zhx】endless【解題報告】

偶數 img lag efi 理解 我們 我沒 ans can

終末

【問題描述】

你是能看到第二題的 friends 呢。

——laekov

沒有盡頭的世界之中,我們想知道0 − 中有多少個數在 進制下和− 進制下的表示方式一樣。(舉個例子,4的−3進制表示為4 = 121−3 = 1 × (−3)2 +

2 × (−3)1 + 1 × (−3)0

【輸入格式】

一行兩個整數 n,k 。

【輸出格式】

一行一個整數代表答案。

【樣例輸入】

21 3

【樣例輸出】

9

【數據範圍與規定】

對於40%的數據,n ≤ 1000。

對於另外30%的數據,k = 2

對於100%的數據,1 ≤ n≤ 1015, 2 ≤k ≤ 103

pdf轉word好不靠譜...

我們先看一下部分分,對於40%的數據,我們可以從1到n枚舉一下,判斷每個數是否符合條件,具體操作是先轉換成k進制數,然後假設(-k)進制數也是這個,乘回去變成原來的10進制,判斷一下是否和以前的10進制相等即可。

對於k=2,我沒有想到什麽解法qwq

對於100%,我們可以先對於i拆成k和-k進制看看

i=a0*k^0+a1*k^1+a2*k^2+...+an*k^n

i=a0*(-k)^0+a1*(-k)^1+a2*(-k)^2+...+an*(-k)^n

那麽兩式相加

2*i=2*a0*k^0+2*a2*k^2+...+2*an*k^n(n%2=0)

i=a0*k^0+a2*k^2+...+an*k^n(n%2=0)

那麽可以看出a1,a3...這些項都為0。

那麽我們就將n拆成k進制數(p[]),通過枚舉每一位選什麽處理即可。

那怎麽處理呢,好像有很多種方法,我的方法大概是:

偶數位必須是0,奇數位依次枚舉

對於拆成的k進制數長度為len,

如果len為偶數,那麽他必須為0,那麽其他的奇數位每一位有k種選擇,乘起來即可

如果len為奇數,那麽當最高位p[len]為p[len]-1及以下時,後面位是可以任意選的,記方案數為tem1

但當最高位選p[len]時,就對其他位有了一些限制,我們從高到低枚舉,p數組偶數位有非0數,那麽比他低的位數可以隨意選擇

不然的話只能在0--p[i]之間枚舉,我們可以把他們(奇數位選擇的上界)整體理解為一個新的k進制數x,另外

還有選擇0的情況,所以最終的ans為tem1+x+1。

技術分享
 1 #include<bits/stdc++.h>
 2 #define ll long long
 3 using namespace std;
 4 ll n;
 5 int k,p[105],len;
 6 int main()
 7 {
 8     scanf("%I64d%d",&n,&k);
 9     while(n){
10         p[++len]=n%k;
11         n/=k;
12     }
13 //    for(int i=len;i>=1;i--)cout<<p[i];
14     ll ans=1;
15     for(int i=1;i<len;i++){
16         if(i&1)
17         ans*=k;
18     }
19     if(len&1)ans*=p[len];
20     ll tem=0,flag=0;
21     if(len&1)
22     for(int i=len-1;i>=1;i--){
23         if(i&1){
24             if(!flag){
25                 tem=tem*k+p[i];
26             }
27             else tem=tem*k+k-1;
28         }
29         else if(p[i])flag=1;
30     }
31     if(len&1)tem++;
32     printf("%I64d\n",ans+tem);
33     return 0;
34 }
ac代碼

【zhx】endless【解題報告】