算法1 二进制映射
同其他题解,$n$的二进制表示数刚好可以表示第$n$个数的某次幂是否使用,可以加个打表避免反复求幂
import java.util.*;
import java.lang.*;
public class Main {
static Scanner scanner = new Scanner(System.in);
public static void main(String[] args) {
int k = scanner.nextInt(), n = scanner.nextInt();
int res = 0, cnt = 0; // res存答案 cnt存当前要计算几次幂
int[] pow = new int[11]; // k的i次方打表 n最多1000 小于2的10次方 即二进制数不超过10位
pow[0] = 1;
for (int i = 1; i < 11; i++) pow[i] = pow[i - 1] * k; // 溢出无影响 用不到
while (n > 0) {
if ((n & 1) == 1)
res += pow[cnt]; // 如果最后一位为1 该次幂有使用到
n >>= 1; // 右移一位
cnt++; // 幂次+1
}
System.out.println(res);
}
}
算法2 找规律
比较菜 看到数列 第一反应还是找规律
发现当第$i$位出现$k^p$后,紧接着出现的就是$a_0 + k^p$、$a_1+k^p$、$\cdots$、$a_{i-2}+k^p$、$a_{i-1}+k^p$,再然后就是$k^{p+1}$,再紧接着···
也就是说,当整数次幂出现时,紧接着出现的就是此前出现的数依次加上本数的结果,之前的所有数加完一遍后,再接着下一个整数次幂
import java.util.*;
import java.lang.*;
public class Main {
static Scanner scanner = new Scanner(System.in);
static int k, n;
static int[] pow = new int[1010];
public static void main(String[] args) {
k = scanner.nextInt();
n = scanner.nextInt();
pow[0] = 1; // 打表 打到超int范围
for (int i = 1; pow[i - 1] < Integer.MAX_VALUE / k; i++) pow[i] = pow[i - 1] * k;
ArrayList<Integer> arr = new ArrayList<>(); // 数列
for (int i = 0; arr.size() < n; i++) { // 模拟数的添加 直到出现第n个数
int len = arr.size(); // 先记录下未添加整数次幂时的个数
arr.add(pow[i]); // 添加整数次幂
// 遍历之前的所有数 把它加上该整数次幂的结果放进数列 直到枚举完所有数或者数列出现第n个数
for (int j = 0; j < len && arr.size() < n; j++) arr.add(arr.get(j) + pow[i]);
}
System.out.println(arr.get(n - 1));
}
}