CCF-CSP真题《202312-2 因子化简》思路+python,c++满分题解
Hulake_ 2024-09-30 09:35:02 阅读 81
想查看其他题的真题及题解的同学可以前往查看:CCF-CSP真题附题解大全
试题编号: | 202312-2 |
试题名称: | 因子化简 |
时间限制: | 2.0s |
内存限制: | 512.0MB |
问题描述: | 题目背景质数(又称“素数”)是指在大于 1 的自然数中,除了 1 和它本身以外不再有其他因数的自然数。
问题描述小 P 同学在学习了素数的概念后得知,任意的正整数 n 都可以唯一地表示为若干素因子相乘的形式。如果正整数 n 有 m 个不同的素数因子 p1,p2,⋯,pm,则可以表示为:n=p1t1×p2t2×⋯×pmtm。
小 P 认为,每个素因子对应的指数 ti 反映了该素因子对于 n 的重要程度。现设定一个阈值 k,如果某个素因子 pi 对应的指数 ti 小于 k,则认为该素因子不重要,可以将 piti 项从 n 中除去;反之则将 piti 项保留。最终剩余项的乘积就是 n 简化后的值,如果没有剩余项则认为简化后的值等于 1。
试编写程序处理 q 个查询:
每个查询包含两个正整数 n 和 k,要求计算按上述方法将 n 简化后的值。 输入格式从标准输入读入数据。
输入共 q+1 行。
输入第一行包含一个正整数 q,表示查询的个数。
接下来 q 行每行包含两个正整数 n 和 k,表示一个查询。
输出格式输出到标准输出。
输出共 q 行。
每行输出一个正整数,表示对应查询的结果。
样例输入
样例输出
样例解释查询一:
n=23×32×234×107
其中素因子 3 指数为 2,107 指数为 1。将这两项从 n 中除去后,剩余项的乘积为 23×234=2238728。
查询二:
所有项均被除去,输出 1。 查询三:
所有项均保留,将 n 原样输出。 子任务40% 的测试数据满足:n≤1000;
80% 的测试数据满足:n≤105;
全部的测试数据满足:1<n≤1010 且 1<k,q≤10。
|
真题来源:因子化简
感兴趣的同学可以如此编码进去进行练习提交
python题解:
<code> # 将整数num用因子形式表示 (因子,幂)
def decompose(num):
ans = []
i = 2
# 检查2-sqrt(n)
while i * i <= num:
tmp = 0
# 素数筛选算法, 筛掉i的倍数,每筛一次,i的幂次+1
while num % i == 0:
tmp += 1
num //= i
if tmp > 0:
ans.append((i, tmp))
i += 1
# 大于sqrt(n)的素因子最多只有1个
if num > 1:
ans.append((num, 1))
return ans
if __name__ == "__main__":
q = int(input())
for i in range(q):
# 乘积结果
mlc = 1
# n:整数 k:阈值
n, k = map(int, input().split())
# 求n以内的所有素数因子,并用因子形式表示
num_primes = decompose(n)
for item in num_primes:
if item[1] >= k:
mlc *= item[0]**item[1]
print(mlc)
运行结果:
C++题解:
<code>#include <bits/stdc++.h>
using namespace std;
inline int read()
{
int x = 0, f = 1;
char c = getchar();
while (c < '0' || c > '9')
{
if (c == '-') f = -1;
c = getchar();
}
while ( c >= '0' && c <= '9')
{
x = x * 10 + c - '0';
c = getchar();
}
return x * f;
}
inline long long LLread()
{
long long x = 0, f = 1;
char c = getchar();
while (c < '0' || c > '9')
{
if (c == '-') f = -1;
c = getchar();
}
while ( c >= '0' && c <= '9')
{
x = x * 10 + c - '0';
c = getchar();
}
return x * f;
}
long long PrimeList[10000]{2, 3};
int PrimeListSize = 2;
void FillPrimeList(long long n = 1e10)
{
long long C = sqrt(n) + 1;
for (long long i = 5; i<= C;++i)
{
bool Flag = 1;
for (int j = 0; j< PrimeListSize; ++j)
{
if (i % PrimeList[j] ==0)
{
Flag = 0;
break;
}
}
if (Flag)
{
PrimeList[PrimeListSize++] = i;
}
}
}
long long Nums[15]{0};
int Ks[15]{0};
int main()
{
int q = read();
long long MaxNum = 0;
for (int i = 1; i<=q; ++i)
{
Nums[i] = LLread();
Ks[i] = read();
MaxNum = MaxNum > Nums[i] ? MaxNum : Nums[i];
}
FillPrimeList(MaxNum);
for (int i = 1; i <= q; ++i)
{
int CurIndex = 0, CurCnt = 0;
long long CurAns = 1;
bool Flag = 1;
while (CurIndex < PrimeListSize)
{
if (Nums[i] % PrimeList[CurIndex] == 0)
{
++CurCnt;
Nums[i] /= PrimeList[CurIndex];
}
else
{
if (CurCnt >= Ks[i]) CurAns *= pow(PrimeList[CurIndex], CurCnt);
++CurIndex;
CurCnt = 0;
}
}
cout << CurAns << '\n';
}
}
运行结果:
声明
本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。