

#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <math.h>
// 欧拉筛法
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的测试范围也确实离谱。。。优化是一点都不想继续优化了,有大神看到,有兴趣的话帮忙在评论区指点指点,拜谢各位大佬!
---因子化简&spm=1001.2101.3001.5002&articleId=135437957&d=1&t=3&u=524327bb3e1d4a2baa4eea7fa76d3f49)
2364

被折叠的 条评论
为什么被折叠?



