Java 查找与3个三角形数字匹配的最大值
众所周知,任何正数最多可以用3个三角形数来表示。( ) 例如:Java 查找与3个三角形数字匹配的最大值,java,algorithm,math,numbers,triangular,Java,Algorithm,Math,Numbers,Triangular,众所周知,任何正数最多可以用3个三角形数来表示。( ) 例如: 11:=10+1 12:=10+1+1 13:=10+3 14:=10+3+1 15:=15 我正在搜索正数n的表示形式,最多搜索3个可能的三角形总和。n可以存在多个表示形式。我对最有成就感的那个感兴趣 对于求和,有没有比2减for和1增for循环更有效的方法 public void printMaxTriangularNumbers(int n){ int[] tri = createTriangularNumbers(100
11:=10+1
12:=10+1+1
13:=10+3
14:=10+3+1
15:=15
我正在搜索正数n
的表示形式,最多搜索3个可能的三角形总和。n
可以存在多个表示形式。我对最有成就感的那个感兴趣
对于求和,有没有比2减for和1增for循环更有效的方法
public void printMaxTriangularNumbers(int n){
int[] tri = createTriangularNumbers(1000);
lbl: for(int i = tri.length-1; ; i--){
int tmp = n - tri[i];
if(tmp == 0){
System.out.println(tri[i]);
break;
}
for(int j=i; j>0; j--){
int tmp2 = tmp - tri[j];
if(tmp2 ==0){
System.out.println(tri[i]);
System.out.println(tri[j]);
break lbl;
}
for(int k=1; k <= j;k++){
if(tmp2 - tri[k] == 0){
System.out.println(tri[i]);
System.out.println(tri[j]);
System.out.println(tri[k]);
break lbl;
}
}
}
}
}
public int[] createTriangularNumbers(int n){
int[] out = new int[n+1];
for(int i=1,sum=0; i<=n;i++){
out[i] = sum += i;
}
return out;
}
public void printMaxTriangularNumbers(int n){
int[]tri=CreateTriangularNumber(1000);
lbl:for(int i=tri.length-1;;i--){
int tmp=n-tri[i];
如果(tmp==0){
系统输出println(tri[i]);
打破
}
对于(int j=i;j>0;j--){
int-tmp2=tmp-tri[j];
如果(tmp2==0){
系统输出println(tri[i]);
系统输出println(tri[j]);
打破lbl;
}
对于(int k=1;k由于三角形数是任何自然数x
满足t=x(x+1)/2
的任何数t
,所以您要解决的是
n=a(a+1)/2+b(b+1)/2+c(c+1)/2
为了找到具有最大可能max(a,b,c)
的解决方案(a,b,c)
。您没有指定只允许具有3个三角形数字的解决方案,因此我假设您也允许形式为(a,b,c,d)
的解决方案,并查找具有最大max(a,b,c,d)
的解决方案
可能有多个解决方案,但始终存在一个最多有3个三角形数的解决方案。由于可以用3个三角形数形成任何数,因此可以用t=0找到最大的三角形数t
,因此可以由3个三角形数本身组成。由于您对最大和感兴趣,largest将是t
,可以用t=x(x+1)/2
计算,其中x=floor((sqrt(1+8n)-1)/2)
(通过求解公式n=x(x+1)/2+d获得)
作为一个实际的例子,以n=218
为例。根据公式,我们得到x=20
和t=210
,这确实是218之前的最大三角形数。在这种情况下,其他三角形数将是6
,1
,因为计算8的唯一方法是使用这些三角形数。据我所见,没有直接公式。需要算法。例如,贪婪方法不起作用。以值90为例:
- 不大于90的最大三角形数为78,剩余为12
- 不大于12的最大三角形数为10。剩余为2
- 现在很明显,我们需要4个条款,这是不可接受的
因此,我会提出一个递归/回溯算法,其中每个递归调用只处理一个求和。递归中的每个级别首先获取可能的最高三角形数,但如果递归调用失败,它将进入第二个最大值并再次进入递归,直到有一个可接受的求和
我们可以使用下列公式:
设Tm为小于或等于c的最大三角形数。
实际上可以得到m的显式公式,即:
下面是一个实现递归的代码段。在运行它时,可以引入一个值,并为其生成三角形求和
函数getTriangularTerms(n,maxTerms){
if(maxTerms==0&&n>0)返回null;//失败:术语太多
if(n==0)返回[];//Ok!返回可以在其前面加上术语的空数组
//允许多次尝试,每次使用
//小三角和:
对于(设k=Math.floor((Math.sqrt(1+8*n)-1)/2);k>=1;k--){
设项=k*(k+1)/2;
//使用递归
让结果=getTriangularTerms(n项,maxTerms-1);
//如果结果不为null,则我们有一个匹配项
if(result)返回[term,…result];//预结束term
}
}
//I/O处理
让输入=document.querySelector(“输入”);
让输出=document.querySelector(“span”);
(input.oninput=function(){//输入中任何更改的事件处理程序
设n=input.value;
let terms=getTriangularTerms(n,3);//最多允许3个术语。
output.textContent=terms.join(“+”);
})();//在页面加载时也执行。
输入号码:
术语:
请解释什么是三角形数字,并为您描述的解决方案显示您的代码。显示比描述更好,尤其是在代码方面。14不是三角形数字。您是对的!更新了问题。我认为您的问题更适合数学领域,最好在数学堆栈上提问改变。我收集到一个三角形数字是一个整数k
,这样就存在一个整数j
和k=j(j+1)/2
。鉴于此,您需要求解2n=j1(j1+1)+j2(j2+1)+j3(j3+1)
对于一些整数j1
,j2
,j3
。这是一个三变量的二次丢番图方程。也许网络搜索这些术语会找到一些资源。此外,我支持math.stackexchange.com的建议。但最多3个求和的最佳结果是190+28…最终分解218
分成四个三角形数字。这与问题的内容不完全相同。当第一次提出问题时,没有明确规定只允许最多3个三角形数字的解决方案,因此我的假设。由于海报为问题添加了更多细节,这使得此解决方案不适合标题中所述,我只是更新了一下t要用标题确认的文本。公式的图片是错误的,代码中使用了正确的公式。@tthoeintausend,it