第四平方和定理,用c语言实现

1.实验题目

1.7【问题描述】

四平方和定理,又称为拉格朗日定理:每个正整数都可以表示为至多4个正整数的平方和。  如果把0包括进去,就正好可以表示为4个数的平方和。比如:5 = 0^2 + 0^2 + 1^2 + 2^2 7 = 1^2 + 1^2 + 1^2 + 2^2 ^符号表示乘方的意思)对于一个给定的正整数,可能存在多种平方和的表示法。 要求你对4个数排序: 0 <= a <= b <= c <= d  并对所有的可能表示法按 a,b,c,d 为联合主键升序排列,最后输出第一个表示法  

【输入】  一个正整数N (N<5000000)  

【输出】  4个非负整数,按从小到大排序,中间用空格分开  

输入范例1 5  

输出范例10 0 1 2  

输入范例2】773535

输出范例2】1 1 267 838 

2.需求分析

本演示程序用VC++6.0编写,完成一个数经过拉格朗日定理所得结果
 输入的形式和输入值的范围:一个正整数N (N<5000000)。在所有输入中,元素的值都是整数
 输出的形式:4个非负整数,按从小到大排序,中间用空格分开
 程序所能达到的功能:每个正整数都可以表示为至多4个正整数的平方和,找出其4个正整数 

 测试数据:
输入范例1 5  

输出范例10 0 1 2  

输入范例2】773535

输出范例2】1 1 267 838 

3.概要设计

1)为了实现上述程序功能,需要定义函数,主函数调用来实现

int f(int n)

{

int a,b,c,d;

先定义四个形参;
2)本程序包含2个函数:
 主函数main()
 4个正整数函数int f(int n)
各函数间关系如下:
main()             int f(int n)

4.详细设计

#include<stdio.h>

#include<math.h>

int MAX=(int)sqrt(5000000);          //利用最大值的开方数使用sqrt函数

int f(int n)

{

int a,b,c,d;

for(a=0;a<=MAX;a++)          //5000000的开方数为MAXa作为最外层的循环,即0<=a<=b<=c<=d,升序

{if(a*a>n)continue;      //满足a*a>n则结束此次循环,跳到下一语句

for(b=a;b<=MAX;b++)

{if(a*a+b*b>n)continue;     //满足a*a+b*b>n即结束此次循环

for(c=b;c<=MAX;c++)

{if(a*a+b*b+c*c>n)continue;  //满足a*a+b*b+c*c>n即结束此次循环

for(d=c;d<=MAX;d++)    //d变化最快

{if(a*a+b*b+c*c+d*d>n)continue;   //满足a*a+b*b+c*c+d*d>n即结束此次循环

if(a*a+b*b+c*c+d*d!=n)continue;//判断4个正整数的平方和是否等于n,不等就结束此次循环

printf("%d %d %d %d\n",a,b,c,d);

return 0;               //输出满足条件的第一个表示法

}

}

}

}

return 0;

}

void main()

{

int n;

printf("请输入N:");

scanf("%d/n",&n);         //输入一个整数

if(n<0||n>5000000)        //根据题目要求的范围

printf("输入的N值不在范围内!\n");

else f(n);

}

5.调试分析
#include<stdio.h>

#include<math.h>

int MAX=(int)sqrt(5000000);          

int f(int n)

{

int a,b,c,d;

for(a=0;a<=MAX;a++)          

{if(a*a>n)continue;      

for(b=a;b<=MAX;b++)

{if(a*a+b*b>n)continue;     

for(c=b;c<=MAX;c++)

{if(a*a+b*b+c*c>n)continue;  

for(d=c;d<=MAX;d++)    

{if(a*a+b*b+c*c+d*d>n)continue;

if(a*a+b*b+c*c+d*d!=n)continue;    

printf("%d %d %d %d\n",a,b,c,d);

return 0;               

}

}

}

}

return 0;

}                                 //时间复杂度T(n)=O(n^4),空间复杂度S(n)=O(1)

void main()

{

int n;

printf("请输入N:");

scanf("%d/n",&n);        

if(n<0||n>5000000)        

printf("输入的N值不在范围内!\n");

else f(n);

}

调试时,先进入main()函数,然后执行输出语句来进行提示,执行输入语句,再根据判断输入的n值来执行相应的语句,要是是1就输出“输入的N值不在范围内!,要是0即调用f(n)函数。f(n)函数有四重循环,最外层为a的循环,接下来就是b,c,d。实现0 <= a <= b <= c <= d ,再根据判断四个数的平方和是否等于n,不等就结束此次循环,要是相等就输入结果,输出第一个就执行return 0语句,结束输出。

6.使用说明

程序名为1.exe,运行环境为VC++6.0。程序执行后显示


根据提示,在第一行先输入一个正整数N (N<5000000),点击换行,下一行输出结果。

7.测试结果

1建立函数
» 输入:5

输出:0 0 1 2

» 输入:773535

输出:1 1 267 838

» 输入:0

输出:输入的N值不在范围内!

 

 

 

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
以下是C语言的代码实现: 1. RSA算法 加密: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <openssl/rsa.h> #include <openssl/pem.h> int main() { // 生成RSA公私钥 RSA *key = RSA_generate_key(2048, RSA_F4, NULL, NULL); // 保存公私钥 FILE *f; f = fopen("private_key.pem", "w"); PEM_write_RSAPrivateKey(f, key, NULL, NULL, 0, NULL, NULL); fclose(f); f = fopen("public_key.pem", "w"); PEM_write_RSAPublicKey(f, key); fclose(f); // 使用公钥加密 char plaintext[] = "hello world"; size_t plaintext_len = strlen(plaintext); unsigned char ciphertext[256]; RSA_public_encrypt(plaintext_len, (unsigned char *)plaintext, ciphertext, key, RSA_PKCS1_OAEP_PADDING); return 0; } ``` 解密: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <openssl/rsa.h> #include <openssl/pem.h> int main() { // 读取私钥 FILE *f; f = fopen("private_key.pem", "r"); RSA *key = RSA_new(); key = PEM_read_RSAPrivateKey(f, &key, NULL, NULL); fclose(f); // 使用私钥解密 unsigned char plaintext[256]; size_t plaintext_len = RSA_private_decrypt(sizeof(ciphertext), ciphertext, plaintext, key, RSA_PKCS1_OAEP_PADDING); return 0; } ``` 2. 模重复平方算法 ```c #include <stdio.h> #include <stdint.h> uint64_t mod_exp(uint64_t base, uint64_t exponent, uint64_t modulus) { uint64_t result = 1; while (exponent > 0) { if (exponent & 1) { result = (result * base) % modulus; } exponent >>= 1; base = (base * base) % modulus; } return result; } ``` 3. 蒙哥马利算法 ```c #include <stdio.h> #include <stdint.h> uint64_t montgomery_reduction(uint64_t x, uint64_t r, uint64_t n, uint64_t n_inv) { // Step 1 uint64_t m = (x * r) % n; // Step 2 uint64_t t = (x + m * n) * n_inv % r; // Step 3 if (t >= r) { return t - r; } else { return t; } } uint64_t mod_exp_montgomery(uint64_t base, uint64_t exponent, uint64_t modulus) { // Step 1 uint64_t r = 1; while (r < modulus) { r <<= 1; } // Step 2 uint64_t n_inv = -modulus % r; // Step 3 base = (base * r) % modulus; // Step 4 uint64_t x = r % modulus; while (exponent > 0) { if (exponent & 1) { x = montgomery_reduction(x * base, r, modulus, n_inv); } base = montgomery_reduction(base * base, r, modulus, n_inv); exponent >>= 1; } // Step 5 return montgomery_reduction(x, r, modulus, n_inv); } ``` 4. 中国剩余定理 ```c #include <stdio.h> #include <stdint.h> uint64_t chinese_remainder_theorem(uint64_t *c, uint64_t *n, uint64_t len) { // Step 1 uint64_t N = 1; for (int i = 0; i < len; i++) { N *= n[i]; } // Step 2 uint64_t x = 0; for (int i = 0; i < len; i++) { uint64_t Ni = N / n[i]; uint64_t Mi = mod_exp_montgomery(Ni, n[i] - 2, n[i]); x += c[i] * Ni * Mi % N; } // Step 3 return x % N; } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值