CCF题库刷题(C语言)---因子化简

CCF题库刷题(C语言)---因子化简_第1张图片

因子化简

#include 
#include 
#include 
#include 

// 欧拉筛法
unsigned *primescacluate(unsigned range, int *n)
{
    *n = 0;
    unsigned *primes = (unsigned *)malloc((range + 10) * sizeof(unsigned));
    bool *isprime1 = (bool *)malloc((range + 10) * sizeof(bool));
    for (int i = 0; i < range + 10; i++)
    {
        isprime1[i] = 0;
    }
    isprime1[0] = 1;
    isprime1[1] = 1;
    for (int i = 2; i < range + 1; i++)
    {
        if (!isprime1[i])
        {
            primes[*n] = i;
            *n += 1;
        }
        for (int k = 0; k < (*n) && primes[k] * i < range + 1; k++)
        {
            isprime1[primes[k] * i] = 1;
            if (i % primes[k] == 0)
                break;
        }
    }
    free(isprime1);
    isprime1 = NULL;
    return primes;
}
    // (2)因子化简问题
int main()
{


    // 录入一个整数N,小于等于1000000000,和一个整数k,要求将N化简,k为阈值
    unsigned int num;
    int q = 0;
    scanf("%d", &q); // 录入求解数据个数
    unsigned int **nums;
    nums = (unsigned int **)malloc(q * sizeof(unsigned int *));
    for (int i = 0; i < q; i++)
    {
        nums[i] = (unsigned int *)malloc(2 * sizeof(unsigned int));
    }

    unsigned max = 0;
    for (int a = 0; a < q; a++)
    {
        scanf("%d %d", &nums[a][0], &nums[a][1]); // 录入整数N以及阈值k
        if (nums[a][0] > max)
            max = nums[a][0]; // 找到最大数,以便计算范围内的素数
    }

    // 调用欧拉筛法
    unsigned int r = 100000; // 计算范围设想设为MAX,但是会报错,设为题目测试的80%:10^5

    int n;
    unsigned int *primes = primescacluate(r, &n);

    // 进行化简操作
    unsigned int *result = (unsigned int *)malloc(q * sizeof(unsigned int));
    if (result == NULL)
    {
        return 0;
    }

    for (int a = 0; a < q; a++)
    {
        result[a] = 1;
    }

    for (int a = 0; a < q; a++)
    {
        int x = 1;
        int **h = (int **)malloc(x * sizeof(int *));
        for (int b = 0; b < n && primes[b] <= nums[a][0]; b++)
        {
            h[x - 1] = (int *)malloc(2 * sizeof(int));
            h[x - 1][0] = primes[b];
            h[x - 1][1] = 0;
            while (nums[a][0] / primes[b] > 1 && nums[a][0] % primes[b] == 0)
            {
                h[x - 1][1] += 1;
                nums[a][0] = nums[a][0] / primes[b];
            }
            if (nums[a][0] / primes[b] == 1 && nums[a][0] % primes[b] == 0)
            {
                h[x - 1][1] += 1;
                x++;
                h = (int **)realloc(h, x * sizeof(int *));
                break;
            }
            x++;
            h = (int **)realloc(h, x * sizeof(int *));
        }


        result[a] = 1;
        for (int c = 0; c < x - 1; c++)
        {
            if (h[c][1] >= nums[a][1])
            {
                result[a] = result[a] * (unsigned int)round(pow((double)h[c][0],(double)h[c][1]));
            }
        }

        for (int c = 0; c < x-1; c++)
        {
            free(h[c]);
        }
        free(h);
        h = NULL;
    }

    for (int h = 0; h < q; h++)
    {
        printf("%d\n", result[h]);
    }
    free(primes);
    primes = NULL;
    free(result);
    result = NULL;
    free(nums);
    nums = NULL;
    return 0;
}

#感想:这难度跃迁的有点离谱,为此去学了质数的三种筛法:朴素筛法、埃筛法、欧拉筛法。实现过程中也是问题不断,C语言的数组、指针使用的难度这回是真正体会到了,商汤AI的RACCON都发现不了一点问题,只能一点点边猜边测去找问题。。。题目要求的10^10的测试范围也确实离谱。。。优化是一点都不想继续优化了,有大神看到,有兴趣的话帮忙在评论区指点指点,拜谢各位大佬!

你可能感兴趣的:(CCF刷题,c语言,算法,数据结构)