Project_Euler-29 题解

本文介绍了解决ProjectEuler第29题的方法,通过使用数据结构优化暴力破解算法,避免数值过大问题,找到最小的满足给定数k次幂等于x的底数y。作者提供了C语言代码实现,包括初始化素数列表、计算最小底数和对应幂次,以及存储结果的数组优化。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Project_Euler-29 题解

标题

题目

1
2

思路

如果暴力破解的话会有一个问题,那就是数值过大的问题,那我们就需要通过对数据结构来进行操作,这样的话会让代码变得很臃肿。

优化思路

其实,对于一个数值,我们并不需要要将其计算出结果,只需要将它们表示为二元组的形式就可以,而且可以去重,例如:

4 2 = 2 4 = ( 2 , 4 ) 4^2 = 2^4 = (2,4) 42=24=(2,4)
6 4 = 3 6 2 = ( 6 , 4 ) 6^4 = 36^2 = (6,4) 64=362=(6,4)

我们让其

给定一个数 x x x ,假设我们想求出最小的满足其 k k k 次幂等于 x x x 的值 y y y,即:
x = y k x = y^k x=yk
我们可以这样做:

从2开始遍历,对于遍历到的每一个值 j j j,我们尝试对其进行平方运算,并记录平方的次数 k k k,截止条件是得出的值小于 x x x,其间,如果发现得到一个等于 x x x的数,说明存在,这个时候返回 j j j,并将次数 k k k保存下来。

这样就得到了一个二元组。

优化代码

由于暴力破解的代码太臃肿了,因此作者没写出暴力的代码,这里之间放出优化代码:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <time.h>
#define MAX_N 100
#define MAX_M 10000

typedef struct ppower {
    int base;
    int power;
} PP;

PP prime_powers;

int arr[MAX_M][MAX_M];

int prime[MAX_N + 5];
void init() {
    prime_powers.base = 1;
    prime_powers.power = 1;
    for (int i = 2; i <= MAX_N; i++) {
        if (!prime[i]) prime[++prime[0]] = i;
        for (int j = 1; j <= prime[0]; j++) {
            if (i * prime[j] > MAX_N) break;
            prime[i * prime[j]] = 1;
            if (i % prime[j] == 0) break;
        }
    }
}

// 得到最小底数和其对应幂数的代码
int get_base(int x) {
    for (int i = 2; i <= MAX_N && i < x; i++) {
        int ans = 1;
        int temp = i;
        while (temp < x) {
            temp *= i;
            ans++;
            if (temp == x) {
                prime_powers.base = i;
                prime_powers.power = ans;
                return i;
            }
        }
    }
    prime_powers.base = x;
    prime_powers.power = 1;
    return x;
}

// 我们没有采用返回结构体的方式,而是定义了一个全局结构体来保存结果
// 这个函数的作用就是返回上一次求底数对应的幂数
int get_power(int x) {
    if (x == prime_powers.base) return prime_powers.power;
    else -1;
}

int main() {
    int ans = 0;
    init();
    
    for (int i = 1; i <= 100; i++) {
        int base = get_base(i);
        int power = get_power(pr);
        printf("i: %d -> base = %d, power = %d\n", i, base, power);
    }
    for (int i = 2; i <= MAX_N; i++) {
    	// base是底数
        int base = get_base(i);
        // power是幂数
        int power = get_power(base);
        for (int j = 2; j <= MAX_N; j++){
            if (arr[base][power * j]) {
                continue;
            } else {
                arr[base][power * j] = 1;
                ans++;
            }
        }
    }
    printf("ans = %d\n", ans);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

若亦_Royi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值