对于给定的数字,我必须输出有多少个三胞胎组成这个数字。还有1 + 1 + 8 = 8 + 1 + 1 = 1 + 8 + 1。
以下代码由用户Klutt提供。我试过了,的确,除了大量外,它确实有效。
int n; /* to store the number */
long i=0; /* counter (long, just to be sure) */
scanf("%d", &n);
/* makes triplets [a, b, c] and looks if the sum of those numbers is equal to the
* given number.
*/
for(int a=1; a<n; a++) {
for(int b=a; b<n; b++) {
for(int c=b; c<n; c++) {
if(a+b+c == n) {
i++;
};
};
};
};
由于较长的CPU时间,我尝试将变量更改为unsigned int和unsigned long,并将for循环更改为其他类型的循环,以查看它们中的任何一个对CPU时间都有影响。
(我对如何真正影响这次一无所知。我的编码经验也几乎为0。)
但是,例如,当我插入一个大于1000的数字时,要花10秒钟以上的时间才能计算出答案。
答案 0 :(得分:0)
您可以进行简单的暴力破解。对于大量用户来说这很慢,但是很容易实现。
int no_triplets=0;
for(int i=1; i<n; i++)
for(int j=1; j<n; j++)
for(int k=1; k<n; k++)
if(i+j+k == n)
no_triplets++;
printf("%d\n", no_triplets);
有很多方法可以改善这种非常简单的算法。例如,最简单的方法之一是使i
,j
和k
的循环转到n-2
,n-i
和n-(i+j)
。当你在的时候。将j
和k
的起始值分别更改为i
和j
。您还可以通过一些基本数学进行优化。例如,给定i
,j
和n
,您可以通过k
计算k=n-(i+j)
。从您的问题来看,假设i
,j
和k
应该大于零似乎是合理的。因此,通过使用一些数学运算和第一个优化,我们可以重写为:
int no_triplets=0;
for(int i=1; i<n-2; i++) {
for(int j=i; j<n-i; j++) {
int k=n-(i+j);
if(k>0)
no_triplets++;
}
}
答案 1 :(得分:0)
这里您要问的基本上是数学问题,而不是编程问题。您要计算的值有一个简单的封闭形式表示形式。
我没有尝试直接导出公式,而是采取了一种捷径并搜索了{{3中的前几个非平凡值(1,1,2,3,4,5,7,8,10) }} –我立即在Online Encyclopedia of Number Sequences中找到了一个匹配项。
所述百科全书对此a(n) = round( (n+3)^2/12 )
序列给出了封闭形式的表示。在C语言中,考虑到序列的偏移量后,可以简单地表示为i = n*n/12
。