AcWing第五场周赛第二题——3727. 乘方相加
题目描述
给定一个长度为 n 的数组 v1,v2,…,vn。
初始时,数组中的所有元素都为 0。
接下来,可以对该数组进行若干次如下操作------对于第 i次操作(i 从 0开始),你可以:
- 要么选择其中一个元素 vpos,将其增加 ki。
- 要么不选择任何元素,直接跳过此次操作。
你可以随时停止操作(不进行任何操作也可以)。
现在,给定 k的值以及一个目标数组 a1,a2,…,an。
请问,能否通过上述操作,将数组 v转化为数组 a。
输入格式
第一行包含整数 T,表示共有 T组测试数据。
每组数据第一行包含两个整数 n,k。
第二行包含 n个整数 a1,a2,…,an。
输出格式
每组数据输出一行结果,能将数组 v转化为数组 a,则输出 YES
,否则输出 NO
。
数据范围
对于前三个测试点,1≤T≤5。
对于全部测试点,1≤T≤1000,1≤n≤30,2≤k≤100,0≤ai≤1016。
输入样例:
5
4 100
0 0 0 0
1 2
1
3 4
1 4 1
3 2
0 1 3
3 9
0 59049 810
输出样例:
YES
YES
NO
NO
YES
解题思路
k进制,仔细观察可以发现,这是考k进制的题。我们只需要将给定的 a1,a2,…,an这个数组中的所有数都用k进制表示出来,最后判断某个位是否超过1,如果有一个位置的值超过1,那么就说明是不可能转化的,否则就是可以转化为目标数组
转为k进制的通用代码
int N = 100;
int[] s = new int[N];
long x = input.nextLong(); for (int j = 0; x > 0; x /= k, j++) { s[j] += (int) (x % k); }
AC代码
1 import java.util.*; 2 3 public class Main { 4 5 static int N = 100; 6 static int[] s = new int[N]; 7 8 public static void main(String[] args) { 9 Scanner input = new Scanner(System.in); 10 int T = input.nextInt(); 11 while (T-- > 0) { 12 int n = input.nextInt(); 13 int k = input.nextInt(); 14 // 清0 15 Arrays.fill(s, 0); 16 while (n-- > 0) { 17 long x = input.nextLong(); 18 for (int j = 0; x > 0; x /= k, j++) { 19 s[j] += (int) (x % k); 20 } 21 } 22 boolean flag = true; 23 for (int i = 0; i < N; i++) { 24 if (s[i] > 1) { 25 flag = false; 26 break; 27 } 28 } 29 if (flag) { 30 System.out.println("YES"); 31 } else { 32 System.out.println("NO"); 33 } 34 } 35 36 } 37 }