将整数拆分为勾股数的问题解决
来源:互联网 发布:ubuntu wine 卸载软件 编辑:程序博客网 时间:2024/05/20 18:03
在群里看到这样一个问题:
解法如下:
#include <stdio.h>#define MAX 500000unsigned g_array[MAX + 1] = {0};#define EVEN(x) (((x)&1)==0)#define ODD(x) (((x)&1)==1)//判断两个数字是否互质的标准算法unsigned __int64 gcd(unsigned __int64 a, unsigned __int64 b) /* Non-recursive version */ { unsigned __int64 ret=1; unsigned __int64 t =0;L: if(a==b || b==0 ) return ret*a; if( b==1 ) return ret; if( a<b) { t = a; a = b; b = t; goto L; } if( EVEN(a) ) { a >>= 1; if( EVEN(b) ) { /* 2*gcd(a>>1, b>>1) */ b >>= 1; ret <<= 1; } /* gcd(a>>1, b) */ else {} } else { if( ODD(b) ) { /* gcd( (a-b)/2, b) */ a -= b; a >>= 1; } else { /* gcd(a, b>>1) */ b >>=1; } } goto L;}//填充全局数组内容void GetArray(){ unsigned __int64 x; unsigned __int64 y; unsigned __int64 a; //直角边长度 unsigned __int64 b; //另一条直角边长度 unsigned __int64 c; //斜边长度 unsigned __int64 t; //三边总长度 for (x = 1; ; x += 1) { //令y的值为最小(为x+1),用勾股数公式求出三边长度 a = x * (x + 1) * 2; b = (x + 1) * (x + 1) - x * x; c = (x + 1) * (x + 1) + x * x; //判断是否可以提前结束循环 if (a + b + c > MAX) { break; } //枚举y,总长度大于MAX时跳出循环 for (y = x + 1; y * (x + y) * 2 <= MAX; y += 1) { //用勾股数公式求出三边长度 a = y * x * 2; b = y * y - x * x; c = y * y + x * x; //保证三边互质 if (gcd(gcd(a, b), c) == 1) { t = a + b + c; //标识所有此总长度的倍数的地方拆分方案数加一 while (t <= MAX) { g_array[t] += 1; t += (a + b + c); } } } }}int main(){ //获取所有数字的解法数 GetArray(); //求出其中解法数为一的个数 int nCount = 0; for (int n = 0; n <= MAX; n += 1) { if (g_array[n] == 1) { nCount += 1; } } printf("%d\n", nCount); return 0;}
答案是54446种
- 将整数拆分为勾股数的问题解决
- 将整数m拆分为n个数字的有序拆分方案数为C(m-1,n-1)
- 把输入整数拆分为连续的正整数之和
- 递归 - 整数拆分为斐波拉契数列的和
- 整数的拆分
- ecnu1009 - 整数的拆分
- 整数的拆分问题
- 整数的加法拆分
- 整数的拆分问题
- 整数的拆分1
- 整数的拆分2
- 整数的拆分3
- 整数的拆分
- 整数的拆分
- 将字符串拆分为数组
- 将指定字符串拆分为两个字段的记录集
- 将bitmap设置为背景的问题解决
- 将一个整数转换为若干连续整数的和
- Aix存储结构
- 售货员
- android中的显示跳转和隐式跳转
- 一排石头的游戏问题
- linux中fork()函数详解
- 将整数拆分为勾股数的问题解决
- matlab 二维高斯分布
- checkStyle 代码有警告怎么办
- ubifs 文件系统-1: overview
- Sencha Touch 2 Map
- codeigniter 实例
- UNIX域套接字实例
- 有关Ubuntu11.04下Android2.3.7源码下载与编译
- 程序化交易系统大全