洛谷 P2558 [AHOI2002]网络传输

题目描述

在计算机网络中所有数据都是以二进制形式来传输的。 但是在进行较大数据的传输时,直接使用该数的二进制形式加以传输则往往传输的位数过多。 譬如要传输 1024 就需要 11 位二进制数。 于是小可可提出了一种数据优化传输的设想,并打算对这一设想进行试验。

该设想是:正整数 的所有方幂以及任意多个互不相等的 k 的方幂之和排成一个递增数列{a(k)n} , 例如当 k =3 时,{a(k)n}的前 7 项为 1(即 3^0)、 3(即 3^1)、 4(即 3^0+3^1)、 9(即 3^2)、10(即 3^0+3^2)、12(即 3^1+3^2)、 13(即 3^0+3^1+3^2)。

如果数d是数列{a(k)n}中的第p项,则可以通过传送k和p这两个数来表示数 d 。由于 k 和 p 这两个相对很小的数就可以表达出很大的数 ,因而理论上可以减少网络传输的位数。

小可可现在请你编写程序把接收到的数k和p所代表的数d计算出来。

输入输出格式

输入格式:

 

文件中以一行的形式存放了两个正整数 k 和 p , 1 < k ≤ 1024 ,

1 ≤ p ≤ 1024 。

 

输出格式:

 

以一行的形式输出问题的解(解的位数不超过 50 位)。

 

输入输出样例

输入样例#1: 复制
3 2
输出样例#1: 复制
3
输入样例#2: 复制
3 7
输出样例#2: 复制
13
思路:

首先,我们将数列中所有数转化为k进制,发现第一项为1,第二项为10,第三项为11,因此第p项所代表的是p的二进制表达式。

我们先将p的二进制求出,然后用高精度,答案就出来了。


#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int k,p;
int c[20][55];
int a[20],ans[55];
void pre(){
    memset(c,0,sizeof(c));
    c[0][1]=1;
    int l=1;
    for(int i=1;i<=11;i++){
        for(int j=1;j<=l;j++)    c[i][j]=c[i-1][j];
        for(int j=1;j<=l;j++)    c[i][j]*=k;
        for(int j=1;j<=l;j++){
            c[i][j+1]+=c[i][j]/10;
            c[i][j]%=10;
        }
        while(l<=53){
            c[i][l+1]+=c[i][l]/10;
            c[i][l]%=10;
            l++;
        }
        l--;
    } 
}
int main(){
    scanf("%d%d",&k,&p);
    memset(a,0,sizeof(a));
    int x=0;
    while(p>0){ a[x++]=p%2;p>>=1; }
    x--;
    pre();
    memset(ans,0,sizeof(ans));
    for(int i=0;i<=x;i++)
        if(a[i])
            for(int j=1;j<=54;j++){
                ans[j]+=c[i][j];
                ans[j+1]+=ans[j]/10;
                ans[j]%=10;
            }
    int l=54;
    while(!ans[l])    l--;
    for(int i=l;i>=1;i--)
        printf("%d",ans[i]);
}




细雨斜风作晓寒。淡烟疏柳媚晴滩。入淮清洛渐漫漫。 雪沫乳花浮午盏,蓼茸蒿笋试春盘。人间有味是清欢。
原文地址:https://www.cnblogs.com/cangT-Tlan/p/7732650.html