数列(规律OR进制转换)

题目描述

给定一个正整数k(3≤k≤15),把所有k的方幂及所有有限个互不相等的k的方幂之和构成一个递增的序列,例如,当k=3时,这个序列是:

1,3,4,9,10,12,13,…

(该序列实际上就是:30,31,30+31,32,30+32,31+32,30+31+32,…)

请你求出这个序列的第N项的值(用10进制数表示)。

例如,对于k=3,N=100,正确答案应该是981。

输入

输入只有1行,为2个正整数,用一个空格隔开:

k N

(k、N的含义与上述的问题描述一致,且3≤k≤15,10≤N≤1000)。

输出

输出计算结果是一个正整数(在所有的测试数据中,结果均不超过2.1*109)。(整数前不要有空格和其他符号)。

样例输入
3 100
样例输出
981

这道题有两种解法,一个是找规律,还有一个是运用进制转换(新思维)
第一种:找规律:
解题思路:

找到规律是这道题目的关键。当k=3时,数列为 1 3 4 9 10 12 13 27 28 30 31 36 37 40 …

                       3的0次方 3的1次   3的2次      3的3次

可以想到,3的i次方(i={0,1,2…})后面的数为分别与前面的数的和。如3的2次方后的3个数(3次方前),分别为
9+1 9+3 9+4 3的3次方后的数为 27+1 27+3 27+4 27+9 27+10 27+12 27+13 依次类推即可。
注意事项:
不要用pow()函数!

#include <stdio.h>
int fun(int b,int d)
{
    int i=1,p=1;
    for(;i<=d;i++)
    {
        p*=b;
    }
    return p;
}
int main()
{
    int i,j,c,n,k,a[1005]={0},count=1;
    scanf("%d %d",&k,&n);
    a[count++]=1;
    a[count++]=k;
    a[count++]=k+1;
    for(i=2;count<=n;i++)
    {
        a[count++]=fun(k,i);
        c=count-1;
        for(j=1;j<c&&count<=n;j++)
        {
            a[count++]=a[j]+a[c];
        }
    }
    printf("%d\n",a[n]);
    return 0;
}

第二种:进制转换
基本思路
进制转换,先用二进制将后面那个数(样例中是100)转换为二进制(100的二进制是1100100),然后把这个二进制数当作k(样例给的第一个数,3)进制,然后将k进制转换为10进制就是答案。
这个思路的来源就是题目中说的结果以10进制表示,启发了我。然后看到题目给的递推过程都用的次方数表示,所以想到了进制转换

#include<iostream>
#include<vector>
using namespace std;
int main(){
    int k,n,result=0,radix=1;
    vector<int> v;
    cin>>k>>n;
    /*10进制转2进制*/
    while(n!=0){
        v.push_back(n%2);
        n=(n-(n%2))/2;
    }
    /*k进制转10进制*/
    for(int i:v){  				//从数组a的"第一个元素"输出到数组a的"最后一个元素"
        result+=i*radix;
        radix*=k;
    }
    cout<<result<<endl;
    return 0;
}

转载于https://blog.dotcpp.com/a/69871

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值