【zhx】endless【解題報告】
終末
【問題描述】
你是能看到第二題的 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【解題報告】