求1到10000中,能构成三角形的数字组合

wjn811 2008-03-04 12:12:29
如题,要求全部的组合。
麻烦高人给出想法和过程。(主要是想法,谢谢)
如果有代码也请不吝赐教。
小弟感激不尽!!!
...全文
951 34 打赏 收藏 转发到动态 举报
写回复
用AI写文章
34 条回复
切换为时间正序
请发表友善的回复…
发表回复
knowledge_Is_Life 2008-05-01
  • 打赏
  • 举报
回复
接分是王道!
UltraBejing 2008-04-30
  • 打赏
  • 举报
回复
lz要干嘛?
Dancing_Sea 2008-03-25
  • 打赏
  • 举报
回复
a的范围
a >= 3;

a * a + a * a + 2 * a + 1 <= a * a + b * b < Max * Max
2a*a + 2a + 1/2 < Max * Max

2(a+1/2) ^2 < max * max;
a < sqrt(max * max / 2)

Dancing_Sea 2008-03-25
  • 打赏
  • 举报
回复
上面错了一点
for(b = a+1; b < maxb; b++) => for(b = a+1; b <= maxb; b++)
Dancing_Sea 2008-03-25
  • 打赏
  • 举报
回复
不知道是什么公司,相信出题人肯定不是要大家写几个疯狂的循环,如果要求在10000亿以内,显然上面的所有算法都无法胜任。
应该是一个比较优化的算法。

1、首先要存储平方结果,算一次就够了,这样可以直接查询,而不是计算平方。设为Sq[Max+1] = {0, 1, 4, 9, ... };
a * a = Sq[a];
2、从简单数据规律看:任何平方的尾数不可能是 2,3,7,8
Flag[] = {1, 1, 0, 0, 1, 1, 1, 0, 0, 1};
a * a + b * b = Sq[a] + Sq[b] = Sqc;
mod = Sqc % 10;
Flag[mod]

3、利用倍数关系,比如(3, 4, 5) => (3*n, 4*n, 5*n)显然都是
4、搜索范围:
a^2 + b^2 = c^2
知道a,搜索一个b,使得存在c,满足上述条件
a < b < c;(由于是组合,所以 需要b > a)
b >= a+1;

b的上限呢?
c至少是 b+1;
a * a + b * b = (b + k) * (b + k);
k 至少大于等于0
a * a = 2 b * k + k * k;
b = (a * a - k * k) / (2 * k) < (a * a) / 2*k <= a * a / 2;
因此b的上限为 a * a / 2
这样,速度就快了很多
for (a)
{
maxb = a * a / 2;
for(b = a+1; b < maxb; b++)
{
c2 = Sq[a] + Sq[b];
mod = c2 % 10;
if (Flag[mod] == 0)
continue;
c = sqrt(c2);
if (Sq[c] == c2)
{
得到一个,并处理倍数关系;
}
}
}

具体就不实现了,有兴趣的朋友可以写一下


medie2005 2008-03-25
  • 打赏
  • 举报
回复
a = 2mn;b = m2-n2 ;c = m2+n2 (m >n,m、n为自然数)
应为:
a = 2mn;b = m^2-n^2 ;c = m^2+n^2 (m >n,m、n为自然数,‘^’为乘方运算符).
medie2005 2008-03-25
  • 打赏
  • 举报
回复
若自然数a、b、c满足:
a = 2mn;b = m2-n2 ;c = m2+n2 (m >n,m、n为自然数)
则:a,b,c是一对勾股数。
于是得到算法:
#include <stdio.h>

int main()
{
const int Max=100;
for( int i=2; i<Max; ++i )
for( int j=1; j<i && i*i+j*j<Max*Max; ++j )
printf("%d^2 + %d^2 == %d^2\n", 2*i*j, i*i-j*j, i*i+j*j);
return 0;
}

若解的个数是S,则复杂度是O(S)。
Dancing_Sea 2008-03-25
  • 打赏
  • 举报
回复
[Quote=引用 26 楼 neglected 的回复:]
我重写下我的程序:

C/C++ code#include<iostream>#include<cmath>usingnamespacestd;intmain()
{intlink[10001] ,i,a,b,c,tempt,aMAX;for(i=0;i<=10000;i++)
link[i]=i*i;//存储边的平方for(c=3;c<=10000;c++)//以最大边(斜边)来考虑{
aMAX=link[c]/2;//a*a最大值 (假定a<b,则a*a<C*C/2)a=1;while(link[a]<aMAX)
{
tempt=link[c]-link[a];//如果存在 link[c]-link[a]==b*b 就组成直角三角形 a,b,cb=(int)sqrt(te…
[/Quote]

你的代码有错误

另外你的复杂度不是 “我的算法的发杂度 n*(sqrt(n*n/2))= O(N*N)”
而是 N*N*N / 6
Dancing_Sea 2008-03-25
  • 打赏
  • 举报
回复
a = 2mn;b = m^2-n^2 ;c = m^2+n^2 (m >n,m、n为自然数,‘^’为乘方运算符).

——这个公式不完备,用在这里显然不对。目前勾股数就没有完备的公式,至少所有的公式没有得到数学证明
这个公式9, 12, 15 (3, 4, 5的3倍)就得不到
不存在m, n使得15 = m^2+n^2 成立
neglected 2008-03-25
  • 打赏
  • 举报
回复
这个题目要求输出 abc,我认为最少也要两重循环

我的算法的发杂度 n*(sqrt(n*n/2))= O(N*N)
neglected 2008-03-25
  • 打赏
  • 举报
回复
我重写下我的程序:



#include <iostream>
#include <cmath>
using namespace std;
int main()
{
int link[10001] ,i,a,b,c,tempt,aMAX;
for(i=0;i <=10000;i++)
link[i]=i*i; //存储边的平方

for(c=3;c<=10000;c++) //以最大边(斜边)来考虑
{
aMAX=link[c]/2; //a*a最大值 (假定a<b,则a*a<C*C/2)
a=1;
while(link[a] <aMAX)
{
tempt=link[c]-link[a]; //如果存在 link[c]-link[a]==b*b 就组成直角三角形 a,b,c
b=(int)sqrt(tempt);
if(link[b]==tempt) //或者改成if(link[b]==tempt) 效果更好
cout <<a <<" "<<b <<" " <<c<<endl;
a++;
}
}
return 0;
}

neglected 2008-03-25
  • 打赏
  • 举报
回复
楼上的思想我明白

我的思想本质上和你的一样


不过你实现需要用过多的标志罢了。
neglected 2008-03-25
  • 打赏
  • 举报
回复
真强悍~~~~~~~~~~~~~~~~~~~
neglected 2008-03-24
  • 打赏
  • 举报
回复
#include <iostream>
#include <cmath>
using namespace std;
int main()
{
int link[10000],i,j,k,sqr,tempt;
for(i=1;i<=10000;i++)
link[i-1]=i*i;
for(i=2;i<=10000;i++)
{
k=link[i]/2;
j=0;
while(link[j]<k)
{
tempt=link[i]-link[j];
sqr=(int)sqrt(tempt);
if(sqr*sqr==tempt)
cout<<j+1<<" "<<sqr<<" "<<i+1<<endl;
j++;
}
}
return 0;
}
neglected 2008-03-24
  • 打赏
  • 举报
回复
不好意思发错了,我算的是三角形的个数;还是普通三角形


见笑



neglected 2008-03-24
  • 打赏
  • 举报
回复
组成三角形要求: 两条小边之和大于最大边

1,2,3~~~~(N-1),N;这列数中以N为最大边的三角形有多少个那?

和为(N+1)的:2+(N-1)=3+(N-2)=4+(N-3)=~~>N 可以组成三角形 [(N-2)/2] 个

和为(N+2)的:3+(N-1)=4+(N-2)=4+(N-3)=~~>N 可以组成三角形 [(N-3)/2] 个

和为(N+3)的:4+(N-1)=5+(N-2)=6+(N-3)=~~>N 可以组成三角形 [(N-4)/2] 个
~~~~
~~~
~~

和最大为 (N-1)+(N-2) 1个

以上过程到过来你就会发现个数是 1,1,2,2,3,3~~~~(N-1),(N-1),N,N(结束)
或者是:1,1,2,2,3,3~~~~(N-1),(N-1),N(结束)

所以只要判断(N-2)的奇偶性;就知道是那种情况了

所以:
int i,n,sum;
sum=0;
for(i=4;i<=10000;i++)
{
n=(i-2)/2;
if((i-2)%2) sum+=2*[(1+n)*n/2]=(1+n)*n
else sum+=2*[(1+n)*n/2]-n=n*n
}
sycorc 2008-03-05
  • 打赏
  • 举报
回复
我这个只判断是三角形的大家看下:
#include "iostream.h"
void main()
{
int a=1,b=1,c=1;
for(c=1;c<=10000;c++)
{
for(b=a;b<=c;b++)
{

for(a=c-b+1;a<=b;a++)
{
if(b+a>c)
cout<<"tri:"<<c<<b<<a<<"\n";
}
}
}

}
aiklo 2008-03-05
  • 打赏
  • 举报
回复
怎么存储啊,我想了下sqrtc=a*a+b*b可以代替c的循环这样可以省掉一个循环。这应该是最简的方法吧
高人指点一二。
zhoufangfei 2008-03-05
  • 打赏
  • 举报
回复
#include <iostream>
using namespace std;

int main()
{
int a,b,c;
for(int i=1;i<10000;i++)
{
for(int j=i;j<10000;j++)
{
for(int k=j;k<10000;k++)
{
if(k*k==i*i+j*j)
{
a=i;
b=j;
c=k;
cout<<a<<'\t'<<b<<'\t'<<c<<endl;
}
}

}
}

return 0;
}

这样子执行a才到1000,就需要5min了,能不能有效一点?
p0303230 2008-03-05
  • 打赏
  • 举报
回复
ding
加载更多回复(14)

33,323

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 新手乐园
社区管理员
  • 新手乐园社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧