ural1057. Amount of Degrees

題目鏈接:http://acm.timus.ru/problem.aspx?space=1&num=1057

1057. Amount of Degrees

Time limit: 1.0 second
Memory limit: 64 MB
Create a code to determine the amount of integers, lying in the set [X;Y] and being a sum of exactlyK different integer degrees of B.
Example. Let X=15, Y=20, K=2, B=2. By this example 3 numbers are the sum of exactly two integer degrees of number 2:
17 = 24+20,
18 = 24+21,
20 = 24+22.

Input

The first line of input contains integers X and Y, separated with a space (1 ≤ X ≤ Y ≤ 231−1). The next two lines contain integers K and B (1 ≤ K ≤ 20; 2 ≤ B ≤ 10).

Output

Output should contain a single integer — the amount of integers, lying between X and Y, being a sum of exactly K different integer degrees of B.

Sample

input output
15 20
2
2
3





具體看代碼,代碼中有對各部分的詳細解釋


<span style="font-size:18px;">#include<cstdio>
#include<iostream>
using namespace std;
int f[35][35];///高度爲i時,有j個1的個數
int changetwo(int x,int b)
{
    int num[35]={0};
    int ans=0;
    int i=0;
    while(x>0)///轉換成b進制下的數
    {
        num[++i]=x%b;
        x/=b;
    }
    int temp=i;///記錄轉換之後的數的長度
    while(num[i]<=1)///找到第一個大於等於2的數
    {
        i--;
    }
    while(i>=1)///從上面找到的位置開始把後面都變成1
    {
        num[i]=1;
        i--;
    }
    while(temp>=1)///把存在數組裏的數組合成一個二進制數
    {
        ans=ans*2+num[temp];
        temp--;
    }
    return ans;
}
///預處理
void init()
{
    f[0][0]=1;
    for(int i=1;i<=31;i++)
    {
        f[i][0]=f[i-1][0];
        for(int j=1;j<=i;j++)
        {
            f[i][j]=f[i-1][j]+f[i-1][j-1];///當前高度爲i時要求j個1爲加上左右子樹的j個1個數
        }
    }
}
int calc(int x,int k)
{
    int tot=0,ans=0;///分別表示當前已經統計出幾個1,符合條件的個數
    for(int i=31;i>0;i--)///從根節點出發向葉子節點查找
    {
        if(x&(1<<i))///找當前節點有沒有1
        {
            tot++;
            if(tot>k)
                break;
            x=x^(1<<i);///找到之後把1去掉
        }
        if((1<<(i-1))<=x)
            ans+=f[i-1][k-tot];///如果x的下一位是1的話,那麼從下一個界定啊開始它的做字數全都需要統計
    }
    if(tot+x==k) ans++;
    return ans;
}
int main()
{
    int x,y;
    int k,b;
    scanf("%d%d%d%d",&x,&y,&k,&b);
    init();
    if(b==2)
        printf("%d\n",calc(y,k)-calc(x-1,k));
    else
    {
        x=changetwo(x,b);
        y=changetwo(y,b);
        printf("%d\n",calc(y,k)-calc(x-1,k));
    }
    return 0;
}</span>


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章