|
本帖最后由 rosynirvana 于 2014-3-27 23:19 编辑
很早之前就有人问我,本想直接拿原来的代码来凑数的,结果昨天因为某些原因又写了类似的代码,所以现在写出来吧……
直接穷举的复杂度非常高,我第一次做的时候,先写好直接穷举的代码,然后去查相关的数学知识,代码写完跑出结果后,直接穷举的代码还没跑出结果,所以在这么大的数字的时候,直接穷举就不必考虑了。
题目的关键是要知道相应的数学知识,直角三角形的三边长可以构造出来,具体可以参考
http://zh.wikipedia.org/wiki/%E5%8B%BE%E8%82%A1%E6%95%B0
- #include <stdio.h>
- int gcd(int, int);
- /* 计算过程中需要判断两个数是否互质,所以一个计算最大公约数的函数是必要的 */
- int count[1500000+1];
- /* 大数组记得要放在静态区 */
- int main()
- {
- int m, n;
- /* 构造所需的两个变量 */
- int num = 0;
- int i;
- for(m=2; m<=1225; ++m)
- /* sqrt(1500000)上取整,计算到1225绝对够了 */
- for(n=1; n<m; ++n)
- if(gcd(m, n) == 1)
- if(m % 2 == 0 || n % 2 == 0){
- int a = m*m - n*n;
- int b = 2*m*n;
- int c = m*m + n*n;
- int length = a+b+c;
- int times = 1;
- while(times * length <=1500000){
- /* 所有勾股数都可以用勾股素数来构造 */
- count[times*length] += 1;
- times += 1;
- }
- }
- for(i=0; i<=1500000; ++i)
- if(count[i] == 1)
- num += 1;
- /* 计算出来后,扫描一遍表格,把只有一种可能的统计下来 */
- printf("%d\n", num);
- return 0;
- }
- /* 计算最大公约数用的函数,个人比较习惯的一种写法,效率应该还可以提高 */
- int gcd(int a, int b)
- {
- while(a > 0 && b > 0)
- if(a > b)
- a %= b;
- else
- b %= a;
- return a > b ? a : b;
- }
复制代码
|
|