【发布时间】:2020-09-04 03:13:08
【问题描述】:
问题如下: 给定两个数 n 和 k。对于区间 [1, n] 中的每个数字,您的任务是计算其不能被 k 整除的最大除数。打印所有这些除数的总和。 注意:k 总是一个素数。 t=3*10^5,1
我对这个问题的看法: 对于 1 到 n 范围内的每个 i,所需的除数是 i 本身,仅当 i 不是 k 的倍数时。 如果 i 是 k 的倍数,那么我们必须找到一个数的最大除数并与 k 匹配。如果不匹配,那么这个除数就是我的答案。否则,第二大除数就是我的答案。
例如,取 n=10 和 k=2,1 到 10 范围内的每个 i 所需的除数为 1, 1, 3, 1, 5, 3, 7, 1, 9, 5。这些除数的和是 36。所以 ans=36。
我的代码适用于一些测试用例,但在一些测试用例中失败了。
#include<bits/stdc++.h>
using namespace std;
#define ll long long int
ll div2(ll n, ll k) {
if (n % k != 0 || n == 1) {
return n;
}
else {
for (int i = 2; i * i <= n; i++) {
if (n % i == 0) {
ll aa = n / i;
if (aa % k != 0) {
return aa;
}
}
}
}
return 1;
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
int t;
cin >> t;
while (t--) {
ll n, k;
cin >> n >> k;
ll sum = 0, pp;
for (pp = 1; pp <= n; pp++) {
//cout << div2(pp, k);
sum = sum + div2(pp, k);
}
cout << sum << '\n';
}
}
在我做错的地方有人可以帮助我,或者建议我一些更快的逻辑来做这个问题,因为我的一些测试用例显示 TIME LIMIT EXCEED
查看所有可能的解释后,我将代码修改如下:
#include<bits/stdc++.h>
using namespace std;
#define ll long long int
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
int t;
cin >> t;
while (t--) {
ll n, i;
ll k, sum;
cin >> n >> k;
sum = (n * (n + 1)) / 2;
for (i = k; i <= n; i = i + k) {
ll dmax = i / k;
while (dmax % k == 0) {
dmax = dmax / k;
}
sum = (sum - i) + dmax;
}
cout << sum << '\n';
}
}
但它仍然为 3 个测试用例提供 TIME LIMIT EXCEED。有人请帮忙。
【问题讨论】:
-
请附上minimal reproducible example。对于我们看不到的代码,我们无能为力
-
您的问题陈述有点可疑。 “注意:k 始终是素数。”
k是什么?该注释是您在文本中提及它的唯一地方 -
@idclev463035818 对不起,先生,只是输入错误。
-
出于好奇:您在哪个竞赛网站找到了挑战?
-
再提示一个:以 n=200, k=7 为例,使用暴力破解程序。您可能会在那里看到一个模式(数字可以被 7、49 整除,...)。然后你需要像 Gauss 那样对从 1 到 100 的数字总和进行的创造性思维。结合所有这些应该引导你走上解决方案的道路。
标签: c++ algorithm math factors sieve-of-eratosthenes