列出给定数字以下的3或5的倍数之和。
这是我的代码,找不到任何不必要的内容。但是hackerrank表示由于超时而终止,时间限制为2秒才能提供预期的输出。 输入的第一行包含“ t”,它表示测试用例的数量。接下来是每行,每行包含一个整数。
#include <stdio.h>
void calc(int a){
int sum = 0;
for(int a0=1; a0<a; a0++){
if(a0%3==0 || a0%5==0){
sum+=a0;
}
}
printf("%d", sum);
}
int main(){
int t;
scanf("%d",&t);
int arr[t];
for(int a0 = 0; a0 < t; a0++){
scanf("%d",&arr[a0]);
}
for(int b=0; b<t; b++){
calc(arr[b]);
printf("\n");
}
return 0;
}
输入
2
10
100
输出必须为
23
2318
如果我们列出所有低于10的自然数,它们是3或5的倍数,则这些倍数的总和为23。
答案 0 :(得分:5)
您正在尝试将给定数字下3或5的所有倍数相加。您是否尝试过在没有for循环的情况下如何做?咱们试试吧。嗯,“ 3或5”需要考虑很多。让我们简化一下,并尝试对99下的3的所有倍数求和:
3+6+9+12+15+...+99
如何优化此加法运算以避免for循环? (在继续阅读之前,先这样做)
现在,如果您知道如何在给定n下求和3的所有倍数,那么您是否有办法在给定n下求和3 或 5的所有倍数?嗯,序列3,6,9,12, 15 ,...,n和5,10, 15 ...,n之间有什么重叠?也许如果您可以将n下的3的倍数相加,并将n下的5的倍数相加,那么您可以摆脱那个overlap吗?
好的,假设我知道数字n下3或5的倍数之和。这是否有助于我找到数字n + 1下3或5的倍数之和?也许我知道calc(n-1)是什么。如果可以的话,那会很棒,因为我可以只用save calc(n-1)而不是重新计算calc(n-1)。如果只有...
答案 1 :(得分:1)
以下是每个人的一些提示和链接:
m = (a - 1) / k
下面有a
个数字,它们可以被k
整除(整数除法)。m * (m + 1) / 2 * k
(由Gaussian sum formula链接到德语Wiki-他们似乎更喜欢Gauß)。小于a
并被3
或5
整除的所有数字的总和与
+ the sum of all numbers smaller than `a` divisible by `3`
+ the sum of all numbers smaller than `a` divisible by `5`
- the sum of all numbers smaller than `a` divisible by `15`
这为您提供了恒定时间算法:
#include <stdio.h>
/* sums the numbers
smaller than `a` that
are divisible by `k`
*/
int s(int a, int k) {
int m = (a - 1) / k;
return m * (m + 1) / 2 * k;
}
/* sums the numbers smaller than
a that are divisible by both
3 and 5
*/
int calc(int a) {
return s(a, 3) + s(a, 5) - s(a, 15);
}
int main(){
int t;
scanf("%d", &t);
int arr[t];
for(int a0 = 0; a0 < t; a0++){
scanf("%d", &arr[a0]);
}
for(int b=0; b<t; b++){
printf("input = %d\n", arr[b]);
printf("%d\n", calc(arr[b]));
}
return 0;
}
示例:
$ ./sumFizzBuzz
4
10
100
1000
10000
23
2318
233168
23331668
对不起,这一定是,这里和“几乎重复”的问题上有太多循环-和废话……
答案 2 :(得分:-3)
#include <stdio.h>
void calc_faster(int a)
{
int mid=0,sum=0;
for(unsigned int i = a-1;i>0;i--)
{if(i%3==0)
{
if(i%5==0)
{
mid=i;
break;
} else sum+=i;
} else if(i%5==0) sum+=i;
}
sum+=mid*(7*mid+15)/30;
printf("%d\n",sum);
}
int main()
{
unsigned int t;
unsigned int temp;
scanf("%d",&t);
unsigned int arr[t];
for(register unsigned int a0 = 0; a0 < t; a0++)
{
scanf("%d",&arr[a0]);
}
for(register unsigned int b=0; b<t; b++)
{
calc_faster(arr[b]);
}
return 0;
}