搜索
查看: 1390|回复: 12
打印 上一主题 下一主题

挑战58

[复制链接]
跳转到指定楼层
楼主
发表于 2014-3-27 23:16:57 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 rosynirvana 于 2014-3-27 23:19 编辑

很早之前就有人问我,本想直接拿原来的代码来凑数的,结果昨天因为某些原因又写了类似的代码,所以现在写出来吧……

直接穷举的复杂度非常高,我第一次做的时候,先写好直接穷举的代码,然后去查相关的数学知识,代码写完跑出结果后,直接穷举的代码还没跑出结果,所以在这么大的数字的时候,直接穷举就不必考虑了。

题目的关键是要知道相应的数学知识,直角三角形的三边长可以构造出来,具体可以参考
http://zh.wikipedia.org/wiki/%E5%8B%BE%E8%82%A1%E6%95%B0

  1. #include <stdio.h>
  2. int gcd(int, int);
  3. /* 计算过程中需要判断两个数是否互质,所以一个计算最大公约数的函数是必要的 */

  4. int count[1500000+1];
  5. /* 大数组记得要放在静态区 */

  6. int main()
  7. {
  8.   int m, n;
  9. /* 构造所需的两个变量 */
  10.   int num = 0;
  11.   int i;
  12.   for(m=2; m<=1225; ++m)
  13. /* sqrt(1500000)上取整,计算到1225绝对够了 */
  14.     for(n=1; n<m; ++n)
  15.       if(gcd(m, n) == 1)
  16.         if(m % 2 == 0 || n % 2 == 0){
  17.           int a = m*m - n*n;
  18.           int b = 2*m*n;
  19.           int c = m*m + n*n;
  20.           int length = a+b+c;
  21.           int times = 1;

  22.           while(times * length <=1500000){
  23.   /* 所有勾股数都可以用勾股素数来构造 */
  24.               count[times*length] += 1;
  25.               times += 1;
  26.          }
  27.     }
  28.     for(i=0; i<=1500000; ++i)
  29.        if(count[i] == 1)
  30.          num += 1;
  31.    /* 计算出来后,扫描一遍表格,把只有一种可能的统计下来 */
  32.   printf("%d\n", num);
  33.   return 0;
  34. }

  35. /* 计算最大公约数用的函数,个人比较习惯的一种写法,效率应该还可以提高 */
  36. int gcd(int a, int b)
  37. {
  38.   while(a > 0 && b > 0)
  39.     if(a > b)
  40.       a %= b;
  41.     else
  42.       b %= a;

  43.   return a > b ? a : b;
  44. }
复制代码

     

点评

赞一个  发表于 2014-3-29 13:58
推荐
 楼主| 发表于 2014-7-29 19:55:06 | 只看该作者
MoreHail 发表于 2014-7-29 19:50
是啊,跑了5、6个小时,都没结果。代码里边,count[1500000+1]是数组么?静态区是什么?怎么放入静态区?

放在所有函数外面定义
推荐
发表于 2014-3-28 11:40:01 | 只看该作者
正需要,赞一个
推荐
 楼主| 发表于 2014-3-27 23:23:37 | 只看该作者
几个注意的要点:
1. 1500000的大数组要放在静态区,不然有可能把函数栈爆掉
(动态分配也可以,不过这么一小段代码放在静态区就可以了)

2. 计算勾股素数,然后再乘以整数倍,这样可以保证求得的三边长不会重复
如果直接用m, n构造,会出现重复情况的

3. 构造勾股素数的条件在此再写一遍:

a = m*m - n*n;
b = 2*m*n;
c = m*m + n*n;
三边长满足这样的约束关系

其中
m > n;
m % 2 == 0 || n % 2 == 0 (m, n至少有一个是偶数)
gcd(m, n) == 1(m和n互质)
板凳
发表于 2014-3-28 09:42:27 | 只看该作者
????????????
5#
发表于 2014-3-28 20:57:34 | 只看该作者
{:soso__17261225861671879680_3:}竟然如此简单..............................
6#
发表于 2014-7-17 17:35:14 | 只看该作者
{:soso_e183:}
7#
发表于 2014-7-29 18:55:59 | 只看该作者
对不起,我数学不好,不知道什么是勾股素数。。。
8#
发表于 2014-7-29 19:31:13 | 只看该作者
这个、我就是直接穷举的。。。{:soso__51be3e80bf36fd0f-84cb9798c2b54967-da186aed5a4735fc1066ec7649be2846.jpg_1:}[mw_shl_code=c,true]#include <stdio.h>
#include <stdlib.h>
int main()
{
        int l=12,m,sum;
    int tri(int a);
    while (l<=1500000)
    {
                m=tri(l);
        sum=sum+m;
        if (m!=0) printf("%d ",sum);
                l++;
    }
        system("pause");
        return 0;
}
int tri(int a)
{
        int i,j,k,x,y,z,p=0;
    for (i=3;i<=a/3;i++)
    {
                for (j=i+1;j<=a/2;j++)
        {
                        k=a-j-i;
            x=i*i;
            y=j*j;
            z=k*k;
            if (z<y||z<x||z<y+x) break;
            if (z==x+y)
            {
                                p=p+1;
                break;
            }       
        }
    }
    if (p==1)
                return p;
    else
                return 0;
}
[/mw_shl_code]有崩溃的赶脚。。。

9#
 楼主| 发表于 2014-7-29 19:42:24 | 只看该作者
MoreHail 发表于 2014-7-29 19:31
这个、我就是直接穷举的。。。{:soso__51be3e80bf36fd0f-84cb9798c2b54967-da186aed5a4735fc1066ec7649be28 ...

穷举没意义
10#
发表于 2014-7-29 19:50:23 | 只看该作者

是啊,跑了5、6个小时,都没结果。代码里边,count[1500000+1]是数组么?静态区是什么?怎么放入静态区?
12#
发表于 2014-7-30 01:39:52 | 只看该作者
rosynirvana 发表于 2014-7-29 19:55
放在所有函数外面定义

哦,我造了,谢啦~~~
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

广播台
特别关注
快速回复 返回顶部 返回列表