- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在从 Euler Project Problem 513, Integral median 解决这个问题:
ABC is an integral sided triangle with sides a≤b≤c. mc is the median connecting C and the midpoint of AB. F(n) is the number of such triangles with c≤n for which mc has integral length as well. F(10)=3 and F(50)=165.
Find F(100000).
分析:
a <= b <= c <= n == 100000
abs(a-b) < c < a+b
Mc = sqrt(2 * a^2+ 2 * b^2 - c^2) / 2
wikipedia Mc
是整数所以 2 * a^2+ 2 * b^2 - c^2
应该是一个完美的正方形并且可以被 4 整除。代码:
#include <stdio.h>
#include <math.h>
#define N 100000
#define MAX(a,b) (((a)>(b))?(a):(b))
void main(){
unsigned long int count = 0;
unsigned long int a,b,c;
double mc;
for (a = 1; a <= N; a++) {
printf("%lu\n", a);
for (b = a; b <= N; b++)
for (c = MAX(b, abs(b-a)); c <=N && c < a+b; c++){
mc = sqrt(2 *a *a + 2 * b * b - c * c)/2.0;
if (mc-(unsigned long)mc == 0)
count++;
}
}
printf("\ncpt == %lu\n", count);
}
问题:
它适用于小型 n
但是解决方案的复杂度太高了,我假设是O(n^3)
(我错了吗?)n = 100000
需要几天时间.
我怎样才能通过数学或算法的方式改进它?
更新
我得到了那些建议:
a
的计算能力外面b
/c
b
的循环和功率外面c
环形。这略微提高了性能。c
不能奇怪。然后 a
和 b
必须具有相同的奇偶校验。这将性能提高了 4 倍。O(N^5/2)
一个基本的解决方案,可以实现O(N^2)
通过使用 O(N^2)
的内存。我还没有测试。最佳答案
由于这是一个欧拉计划问题,您应该能够在现代计算机上用大约一分钟的计算时间来完成它。他们并不总是坚持这一点,但这表明如果常量不是太差,运行时间 k*n^2
或 k*n^2*log(n)
可能没问题,但可能不是 k*n^2.5
或 k*n^3
。
正如 SleuthEye 评论的那样,边 c 必须是偶数,否则平方根的内部必须是奇数,因此取平方根除以 2 不能得到整数。
您可以将等式简化为 4(mc^2+(c/2)^2) = 2(a^2+b^2)
。
这是一种方法:创建左右两个字典。对于每个,让键为等式那一侧的可能值,并让值成为产生键的 (mc,c/2)
或 (a,b)
对的列表。对于正确的字典,我们只需要考虑 a
和 b
的奇偶性相同的地方,以及 1<=a<=b<=n
的地方。对于左边,我们只需要考虑 1<=c/2<=n/2
和 1<=mc<=sqrt(3)/2 n
以来的 4mc^2 = 2a^2+2b^2-c^2 <= 3b^2 <=3n^2
。
然后遍历可能的键,并比较每个字典中值的元素,找到兼容的 ((mc,c/2),(a,b))
对的数量,其中 b <= c < a+b
。这个内部步骤不是常数时间,但列表的最大和平均长度不会太长。将 n 写为两个平方和的方法大致对应(最多单位)高斯整数中将 n 分解的方法,正如最大的 number of factors of an integer 不会增长太快一样,高斯整数也是如此。此步骤对于任何 O(n^epsilon)
都需要 epsilon>0
时间。因此,对于任何 O(n^(2+epsilon))
,总运行时间为 epsilon>0
。
在实践中,如果内存不足,您可以构建部分字典,其中的键被限制在特定范围内。这也可以很好地并行化。
关于c - 如何优化我的代码以查找所有可能的积分三角形的所有积分中位数,其中 a <= b <= c <= 100000?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29992720/
我有两种结构,Header 和Session,它们都符合协议(protocol)TimelineItem。 我有一个 Array 由 TimelineItem 组成,如下所示: [Header1, S
这个问题在这里已经有了答案: Multiple assignment and evaluation order in Python (11 个答案) 关闭 6 年前。 我刚接触python所以想问你
我试图找到一种方法来在 R 中获取 A、A、A、A、B、B、B、B、B 的所有可能的唯一排列的列表。 组合最初被认为是获得解决方案的方法,因此组合的答案。 最佳答案 我认为这就是你所追求的。 @bil
我怎样才能将两个给定的向量混合成一个新的向量,它以交替的顺序保存它们的值。 (f [a a] [b b]) ; > [a b a b] 这是我想到的: (flatten (map vector [:a
这是我的第一个问题,我开始学习Python。之间有区别吗: a, b = b, a + b 和 a = b b = a + b 当您在下面的示例中编写它时,它会显示不同的结果。 def fib(n):
这个问题在这里已经有了答案: Why is there an injected class name? (1 个回答) 12 个月前关闭。 我不知道如何解释: namespace A { struct
我尝试了一些代码来交换 Java 中的两个整数,而不使用第三个变量,使用 XOR。 这是我尝试过的两个交换函数: package lang.numeric; public class SwapVars
假设类 B 扩展类 A,并且我想为 B 声明一个变量。什么更有效?为什么? B b或 A b . 最佳答案 您混淆了两个不同的概念。 class B extends A { } 意味着B 是 A .
我不确定这个问题的标题是什么,这也可能是一个重复的问题。所以请相应地指导。 我是 python 编程的新手。我有这个简单的代码来生成斐波那契数列。 1: def fibo(n): 2: a =
我在谷歌上搜索了有关 dynamic_cast 的内容,我发现显式地将基类对象转换为派生类指针可能是不安全的。但是当我运行一些示例代码来检查它时,我没有收到任何错误。请在下面找到我的代码: class
这个问题在这里已经有了答案: What is this weird colon-member (" : ") syntax in the constructor? (14 个答案) 关闭 8 年前。
在不重现产生非整数值的表达式的情况下实现以下目标的惯用方法是什么(在我的真实情况下,该值是在我不想重现的冗长查询之后计算为百分比的): SELECT * FROM SomeTable WHERE 1/
在析构中,这两个代码的结果确实不同。我不确定为什么。 提示说 const [b,a] = [a,b] 将导致 a,b 的值为 undefined (从左到右的简单分配规则)。我不明白为什么会这样。 l
C++ Templates - The Complete Guide, 2nd Edition介绍max模板: template T max (T a, T b) { // if b < a th
我最近开始学习代码(Java),并根据第 15.17.3 节在 Oracle 网站上查找了模运算符。以下链接: http://docs.oracle.com/javase/specs/jls/se8/
无法理解以下行为。 d1 := &data{1}; 的区别d1 和 d2 := 数据{1}; &d1。两者都是指针,对吧?但他们的行为不同。这里发生了什么 package main import "f
这个问题在这里已经有了答案: How to make loop infinite with "x = y && x != y"? (4 个回答) How can i define variables
在我的程序中,当我调试我的代码时,它似乎在我生成的代码中的某处 X1=['[a,a,a]','[b,b,b]'] 还有我生成的其他地方 X2=[[a,a,a],[b,b,b]] 当我想添加这两个列表然
我试图使用递归将两个整数相乘,并意外编写了这段代码: //the original version int multiply(int a, int b) { if ( !b ) retu
我有一个列表中数字之间所有可能的操作组合: list = ['2','7','8'] 7+8*2 8+7*2 2*8+7 2+8*7 2-8*7 8-2/7 etc 我想知道是否可以说像 ('7*2+
我是一名优秀的程序员,十分优秀!