搜索
查看: 1395|回复: 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-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-7-29 19:42:24 | 显示全部楼层
MoreHail 发表于 2014-7-29 19:31
这个、我就是直接穷举的。。。{:soso__51be3e80bf36fd0f-84cb9798c2b54967-da186aed5a4735fc1066ec7649be28 ...

穷举没意义
地板
 楼主| 发表于 2014-7-29 19:55:06 | 显示全部楼层
MoreHail 发表于 2014-7-29 19:50
是啊,跑了5、6个小时,都没结果。代码里边,count[1500000+1]是数组么?静态区是什么?怎么放入静态区?

放在所有函数外面定义
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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