【C++/二进制枚举+快速幂】[NOIP2006 普及组] 数列

184 阅读2分钟

[NOIP2006 普及组] 数列

题目描述

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

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

(该序列实际上就是:30,31,30+31,32,30+32,31+32,30+31+32,3^0,3^1,3^0+3^1,3^2,3^0+3^2,3^1+3^2,3^0+3^1+3^2,…

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

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

输入格式

22个正整数,用一个空格隔开:

kNk NkkNN的含义与上述的问题描述一致,且3k15,10N10003≤k≤15,10≤N≤1000)。

输出格式

11个正整数。(整数前不要有空格和其他符号)。

样例 #1

样例输入 #1

3 100

样例输出 #1

981

提示

NOIP 2006 普及组 第四题

题解

(题目为啥要强调用十进制输出呢,明明就是故意提醒)

分析一下样例

k=3k=3时,数列为:1,3,4,9,10,12,13..1,3,4,9,10,12,13..

转换成三进制就是:1,10,11,100,101,110,111..1,10,11,100,101,110,111..

看起来像是二进制,转化成十进制看看

1,2,3,4,5,6,7..1,2,3,4,5,6,7..

显然,第nn项就是nn.

程序就把这个过程逆回去,先把nn转换成二进制,再把它当成KK进制,重新转换为十进制.

AC代码【大佬的】--转自洛谷 hongzy

#include <iostream>
#include <stack>
#include <cmath>
using namespace std;

long long k, n, ans;
stack<int> S;

int main() {
    cin >> k >> n;
    while(n) S.push(n & 1), n >>= 1;
    while(!S.empty()) ans += S.top() * pow(k, S.size()-1), S.pop();
    cout << ans << endl;
    return 0;
}

AC代码【根据大佬题解思路写】

#include<bits/stdc++.h>
#define ts ios::sync_with_stdio (false);cin.tie(0);
using namespace std;
//==================Define==========================
#define INF 99999999
#define MOD 1000000007

//递归快速幂
long long int qpow(long long int a,long long int n)
{
    if ( n == 0 )
        return 1;
    else if ( n % 2 == 1 )
        return qpow(a, n - 1) * a ;//mod
    else {
        long long int temp = qpow(a, n / 2) ;//mod
        return temp * temp ;//mod
    }
}

//==================================================

string x_to_2(long long int x)
{
    string ans;
    while(x)
    {
        long long int r=x%2;
        ans. push_back(r+'0');
        x/=2;
    }
    return ans;
}

int64_t k_to_10(long long int k,string s)
{
    int64_t ans=0;

    for(long long int i=0;i<s.size();i++)
    {
        ans+=(s[i]-'0')*qpow(k,i);
    }
    return ans;
}

int main()
{
    ts;
    long long int n,k;
    cin>>k>>n;
    string s=x_to_2(n);

    cout<<k_to_10(k,s)<<endl;

    return 0;
}

//2022.7.6