Distinct powers
Consider all integer combinations of
for 2≤a≤5 and 2≤a≤5:
22=4,23=8,24=16,25=3232=9,33=27,34=81,35=24342=16,43=64,44=256,45=102452=25,53=125,54=625,55=3125
If they are then placed in numerical order, with any repeats removed, we get the following sequence of 15 distinct terms:
4,8,9,16,25,27,32,64,81,125,243,256,625,1024,3125
How many distinct terms are in the sequence generated by
for 2≤a≤100 and 2≤b≤100?
不同的幂
考虑所有满足2≤a≤5和2≤b≤5的幂
:
22=4,23=8,24=16,25=3232=9,33=27,34=81,35=24342=16,43=64,44=256,45=102452=25,53=125,54=625,55=3125如果把这些幂从小到大排列并去重,可以得到如下由15个不同的项组成的数列:
4,8,9,16,25,27,32,64,81,125,243,256,625,1024,3125
考虑所有满足2≤a≤100和2≤b≤100的幂
,将它们排列并去重所得到的数列有多少个不同的项?
这个题就是求2-100的2-100的幂次的个数,切不重复,问题就是如何去找到重复的那些数;
来看一个例子:
![]()
那么这就是被重复计算的数
那么如何去进行判断呢,通过幂次来,这个幂次不管如何边他最终都是6;
那就可以直接用2^6去标记 上面个两个
标记他们已经求过了,这个和筛法很相识,那么如何实现看下面的代码:
#include <stdio.h> #include <math.h> #define MAX_N 100 int dir[MAX_N + 5] = {0};//用来存储当前数1次表示的那个数,通过这个数幂次增加还可以得到本身的那 int f[MAX_N + 5][MAX_N + 5];//一维用来记录下标,二维用来记录幂次 void getXY(int a, int b, int *x, int *y) {//来获取到x和y int temp = a; *x = dir[a];//x等于当前数幂次1次的那个数 *y = 0;//y获取幂次,如果x变小,那么y就要变大 while (temp != 1) *y += b, temp /= *x; return ; } void filter(int i, int x, int y) { for (int k = 2; k <= y; k++) { if (y % k) continue; int a1 = k;//和例子的那个一样如果y为6,这里a1可能为2 int a2 = y / k;//那么a2可能就为3 if (a1 * log10(x) <= log10(MAX_N) && pow(x, a1) > i) { //第一个条件防止越界超过100,第二个条件防止这个x的a1幂次还没有本身大,就标记到前面的数去了 f[(int)pow(x, a1)][a2] = 1; } } return ; } int main() { dir[1] = 1; for (int i = 2; i <= MAX_N; i++) { if (dir[i]) continue; for (int j = i; j <= MAX_N; j *= i) { dir[j] = i;//获取每个数最小的那个幂次数,比如4,8,16都是2 } } for (int i = 2; i <= MAX_N; i++) { for (int j = 2; j <= MAX_N; j++) { if (f[i][j]) continue; int x, y;//假如i=64,j=2,那么x=2,y=12; //会发现x^y = 2 ^ 12 = 64 ^ 2; getXY(i, j, &x, &y); filter(i, x, y); } } int cnt = 0; for (int i = 2; i <= MAX_N; i++) { for (int j = 2; j <= MAX_N; j++) { if (f[i][j]) continue; cnt += 1; } } printf("%d\n", cnt); return 0; }
最终答案:9138