【算法】算法中的趣味数学(二)

本文涉及的产品
云解析 DNS,旗舰版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
全局流量管理 GTM,标准版 1个月
简介:

求π的近似算法

  用两种方法编程求π的近似值。
  实例解析:
  1、用“正多边形逼近”的方法求出π的近似值
  我国的祖冲之就是用这种方法在世界上第一个得到精确度达小数点后第6位π值的。
  利用圆的内接正六边形边长等于半径特点将边数翻番,做出正十二边形,求出边长,重复这个过程,就可获得所需精度的π的近似值。
  假设单位圆的内接多边形的边长为2b,边数为i,则边数加倍后新的正多边形的边长为:
  周长为2ix (其中i为加倍前的正多边形的边数)
  2、利用随机数法求π的近似值
  基本思路是:在一个单位边长的正方形中,以边长为半径,以一个顶点为圆心,在正方形上做四分之一圆。随机向正方形内扔点,若落入四分之一圆内则计数。重复向正方形内扔足够多的点,将落入四分之一圆内的计数除以总的点数,其值就是π值四分之一的近似值。
  程序如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include <stdio.h>
#include <math.h>
#include <time.h>
#include <stdlib.h>
#define N 30000
int  main()
{
     double  e = 1.0, b = 0.5, c, d;  //e为边长,b为边长的一半
     long  int  i;                        //i: 正多边形边数
     float  x, y;
     int  c2 = 0, d2 = 0;
     puts ( "\n >> Result of Regular Polygon Approximating:" );
     for (i = 6;    ; i *= 2)
     {           //正多边形边数加倍
         d = 1.0 -  sqrt (1.0 - b*b);  
         b = 0.5 *  sqrt (b*b + d*d);   //b为新多边形边长的一半
         if (2*i*2*b – i*e < 1e-15)
             break ;                       //精度达1e-15则停止计算
             e = 2*b;                      //保存新多边形的边长
     }
     printf ( "-----------------------------------------\n" );
     /*以下输出π值和正多边形的边数*/
     printf ( ">>pi=%.15lf\n" ,2*i*b);
     printf ( ">>The number of edges of required polygon:%ld\n" ,i);
     printf ( "-----------------------------------------\n" );
     randomize();
     while (c2++ <= N)
     {
         x = random(101);       //x:坐标。
         y = random(101);       //y:坐标。
         if (x*x + y*y <= 10000)    //判断点是否落在圆内
             d2++;
     }
     puts ( "\n >> Result of Random Number Method:" );
     printf ( "----------------------------------------\n" );
     printf ( " >> pi=%f\n" ,4.*d2/N);     //输出求出的π值
     printf ( "----------------------------------------\n" );
     puts ( "\n Press any key to quit..." );
     getch();
     return  0;
}


角谷猜想
  日本一位学生发现一个奇妙的“定理”,请角谷教授证明,而教授无能为力,于是产生角谷猜想。猜想的内容是:任意给一个自然数,若为偶数则除以2,若为奇数则乘3加1,得到一个新的自然数,然后按照上面的法则继续演算,若干次后得到的结果必然为1。请编程验证。
  实例解析:
  题目给出的处理过程很清楚,直接进行验证即可。
  程序如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <stdio.h>
int  main()
{
     int  n, count = 0;
     printf ( ">>Please input a number to verify(0 to quit):" );
     scanf ( "%d" ,&n);       //输入任一整数
     while (n != 0)
     {
         printf ( ">>------Results of verification:-------\n" );
         do
         {
             if (n % 2)
             {
                 n = n*3 + 1;            //若为奇数,n乘3加1
                 printf ( ">>Step No.%d: %d*3+1=%d\n" ,++count,(n-1)/3,n);
             }
             else
             {
                 n /= 2;                //若为偶数n除以2
                 printf ( ">>Step No.%d: %d/2=%d\n" ,++count,2*n,n);
             }
         } while (n != 1);              //n不等于1则继续以上过程
         printf ( ">> -----------------------  ----------\n" );
         printf ( ">>Please input a number to verify(0 to quit):" );
         scanf ( "%d" ,&n);       //输入任一整数
     }
     puts ( "\n Press any key to quit..." );
     getch();
     return  0;
}


四方定量
  数论中著名的“四方定理”讲的是:所有自然数至多只要用4个数的平方和就可以表示,请编程验证此定理。
  实例解析:
  对4个变量采用穷举试探的方法进行计算,满足要求时输出计算结果。
  程序如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <stdio.h>
void  verify_four_squares( int  number)
{
     int  i,j,k,n;
     for (i = 1; i < number/2; i++)   //穷举法。试探i,j,k,n的不同值
         for (j = 0; j < i; j++)
             for (k = 0; k < j; k++)
                 for (n = 0; n < k; n++)
                     if (number == i*i + j*j + k*k + n*n)
                     {
                         printf ( ">>%d=%d*%d+%d*%d+%d*%d+%d*%d\n" ,
                         number,i,i,j,j,k,k,n,n);
                         return ;
                     }
}
int  main()
{
     int  number = 1;
     while (number != 0)
     {
         printf ( ">>Please input a number to verify(0 to quit):" );
         scanf ( "%d" ,&number);       //输入任一整数
         if (number == 0)
             break ;
         printf ( ">>------Results of verification: ----\n" );
         verify_four_squares(number);
         printf ( ">>-----------------------------------\n" );
     }
     puts ( "\n Press any key to quit..." );
     getch();
     return  0;
}


卡布列克常数
    任意一个4位数,只要他们各个位上的数字是不完全相同的,就有如下规律:
  将组成该4位数的4个数字由大到小排列,形成由这4个数字构成的最大的4位数;
  将组成该4位数的4个数字由小到大排列,形成由这4个数字构成的最小的4位(如果4位数中含有0,则得到的数不足4位);
  求两个数的差,得到一个新的4位数(高位零保留)
  重复以上过程,最后得到的结果是6174,这个数被称为卡布列克数。请编程验证卡布列克数。
  实例解析:
   题目给出的处理过程很清楚,可按题目叙述直接进行验证。
   程序如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
#include <stdio.h>
void  vr6174( int );
void  parse_sort( int  num,  int  *each);
void  max_min( int  *each,  int  *max,  int  *min);
void  parse_sort( int  num,  int  *each);
int  count = 0;
int  main()
{
     int  n = 1;
     while (n != 0)
     {
         printf ( ">>Please input a 4-digit number to verify(0 to quit): " );
         scanf ( "%d" ,&n);       //输入任一整数
         if (n == 0)
             break ;
         printf ( ">>-----Results of verification: ------\n" );
         count = 0;
         vr6174(n);            //调用函数进行验证
         printf ( ">> ----------------------------------\n" );
     }
     puts ( "\n Press any key to quit..." );
     getch();
     return  0;
}
void  vr6174( int  num)
{
     int  each[4], max, min;
     if (num != 6174 && num)
     //若不等于6174且不等于0则进行运算
     parse_sort(num,each);         //将整数分解,数字存入each数组中
     max_min(each,&max,&min);     //求数字组成的最大值和最小值   
     num = max - min;               //求最大值和最小值的差
     printf ( ">> Step No.%d:  %d-%d=%d\n" ,++count,max,min,num);  //输出该步计算过程
     vr6174(num);          //递归调用自身继续进行卡布列克运算
     }
}
void  parse_sort( int  num, int  *each)
{
     int  i,*j,*k,temp;
     for (i = 0; i <= 4; i++)
     {         //将NUM分解为数字
         j = each + 3 - i;
         *j = num%10;
         num /= 10;
     }
     for (i = 0; i < 3; i++)      //对各数字从小到大进行排序
     for (j=each,k=each+1; j < each+3-i; j++,k++)
         if (*j > *k)
         {
             temp = *j;
             *j = *k;
             *k = temp;
         }
     return ;
}
//下面函数将分解的数字还原为最大整数和最小整数
void  max_min( int  *each,  int  *max,  int  *min)
{
     int  *i;
     *min = 0;
     for (i = each; i < each+4; i++)      //还原为最小的整数
         *min = *min * 10 + *i;
     *max = 0;
     for (i = each+3; i >= each; i--)     //还原为最大的整数
         *max = *max * 10 + *i;
     return ;
}


本文转自infohacker 51CTO博客,原文链接:http://blog.51cto.com/liucw/1171361


相关文章
|
7月前
|
存储 安全 算法
|
7月前
|
人工智能 算法 测试技术
【数学】【排序】【C++算法】3027人员站位的方案数
【数学】【排序】【C++算法】3027人员站位的方案数
|
7月前
|
算法 测试技术 C++
【动态规划】【数学】【C++算法】1449. 数位成本和为目标值的最大数字
【动态规划】【数学】【C++算法】1449. 数位成本和为目标值的最大数字
|
7月前
|
算法 测试技术 C++
【动态规划】【 数学】C++算法:514自由之路
【动态规划】【 数学】C++算法:514自由之路
|
7月前
|
存储 算法 Serverless
【C/C++ 数据结构】深入探索数据结构中算法复杂度:从C++和数学的视角
【C/C++ 数据结构】深入探索数据结构中算法复杂度:从C++和数学的视角
79 0
|
存储 人工智能 算法
【AcWing算法基础课】第四章 数学知识(未完待续)(3)
根据下面公式来预处理出等式右边的组合数的值,那么等式左边就可以用等式右边已经算过的值来进行计算(有点像dp)。
81 0
|
人工智能 算法 BI
【AcWing算法基础课】第四章 数学知识(未完待续)(2)
从2到n枚举每个数,删掉其所有的倍数,枚举完之后,没有被删掉的数为质数。
113 0
|
6月前
|
算法 Java Go
斐波那契数列是一个非常经典的数学问题,在计算机科学中也经常被用作算法设计和分析的例子。
斐波那契数列是一个非常经典的数学问题,在计算机科学中也经常被用作算法设计和分析的例子。
|
5月前
|
算法 安全 网络安全
支付系统,网络安全06----支付安全---,机密性,加密算法,目前最流行的加密算法,AES加密算法,目前最流行的非对称加密算法RSA,对称加密和非对称加密的优缺点,非对称加密是基于非常复杂的数学算法
支付系统,网络安全06----支付安全---,机密性,加密算法,目前最流行的加密算法,AES加密算法,目前最流行的非对称加密算法RSA,对称加密和非对称加密的优缺点,非对称加密是基于非常复杂的数学算法
|
6月前
|
算法 数据挖掘 定位技术
算法必备数学基础:图论方法由浅入深实践与应用
算法必备数学基础:图论方法由浅入深实践与应用