论坛交流
首页办公自动化| 网页制作| 平面设计| 动画制作| 数据库开发| 程序设计| 全部视频教程
应用视频: Windows | Word2007 | Excel2007 | PowerPoint2007 | Dreamweaver 8 | Fireworks 8 | Flash 8 | Photoshop cs | CorelDraw 12
编程视频: C语言视频教程 | HTML | Div+Css布局 | Javascript | Access数据库 | Asp | Sql Server数据库Asp.net  | Flash AS
当前位置 > 文字教程 > C语言程序设计教程
Tag:新手,函数,指针,数据类型,对象,Turbo,入门,运算符,数组,结构,二级,,tc,游戏,试题,问答,编译,视频教程

C趣味程序百例(25)

文章类别:C语言程序设计 | 发表日期:2008-9-24 14:44:43

77.波松瓦酒的分酒趣题
78.求π的近似值(1)
79.求π的近似值(2)




77.波松瓦酒的分酒趣题
   法国闻名数学家波瓦松在表年时代研究过一个有趣的数学问题:某人有12品脱的啤酒一瓶,想从中倒出6品脱,但他没有6品脱的容器,仅有一个8品脱和5品脱的容器,怎样倒才能将啤酒分为两个6品脱呢?
*问题分析与算法设计
   将12品脱酒 8品脱和5品脱的空瓶平分,可以抽象为解不定方程:
                  8x-5y=6
   其意义是:从12品脱的瓶中向8品脱的瓶中倒x次,并且将5品脱瓶中的酒向12品脱的瓶中倒y次,最后在12品脱的瓶中剩余6品脱的酒。
   用a,b,c代表12品脱、8品脱和5品脱的瓶子,求出不定方程的整数解,按照不定方程的意义则倒法为:
            a -> b -> c ->a
               x     y
   倒酒的规则如下:
   1) 按a -> b -> c ->a的顺序;
   2) b倒空后才能从a中取
   3) c装满后才能向a中倒
   按以上规则可以编写出程序如下:
*程序与程序注释
#include<stdio.h>
void getti(int a,int y,int z);
int i;           /*最后需要分出的重量*/
void main()
{
   int a,y,z;
   printf("input Full a,Empty b,c,Get i:"); /*a 满瓶的容量  y:第一个空瓶的容量  z:第二个空瓶的容量*/
   scanf("%d%d%d%d",&a,&y,&z,&i);
   getti(a,y,z);           /*按a -> y -> z -> a的操作步骤*/
   getti(a,z,y);           /*按a -> z -> y -> a的步骤*/
}
void getti(int a,int y,int z)   /*a:满瓶的容量  y:第一个空瓶的容量  z:第二个空瓶的容量*/
{
   int b=0,c=0;           /* b:第一瓶实际的重量  c:第二瓶实际的重量*/
   printf("   a%d b%d c%d\n %4d%4d%4d\n",a,y,z,a,b,c);
   while(a!=i||b!=i&&c!=i)      /*当满瓶!=i或另两瓶都!=i*/
   {
      if(!b)
      {  a-=y; b=y;}    /*假如第一瓶为空,则将满瓶倒入第一瓶中*/
      else if(c==z)
      {  a+=z; c=0;}    /*假如第二瓶满,则将第二瓶倒入满瓶中*/
      else if(b>z-c)    /*假如第一瓶的重量>第二瓶的剩余空间*/
      { b-=(z-c);c=z;}    /*则将装满第二瓶,第一瓶中保留剩余部分*/
      else{ c+=b; b=0;}   /*否则,将第一瓶全部倒入第二瓶中*/
      printf(" %4d %4d %4d\n",a,b,c);
   }
}
*运行结果

   
*思考题
   上面的程序中仅给出了两种分酒的方法,并没有找出全部的方法。请设计新的算法,找出全部的分酒方法,并找出一种倒酒次数最少的方法。

----------------------------------------------------------

78.求π的近似值
   请利用“正多边形逼近”的方法求出π的近似值
*问题分析与算法设计
   利用“正多边形逼近”的方法求出π值在很早以前就存在,我们的先人祖冲之就是用这种方法在世界上第一个得到精确度达小数点后第6位的π值的。
   利用圆内接正六边形边长等于半径的特点将边数翻番,作出正十二边形,求出边长,重复这一过程,就可获得所需精度的π的近似值。
   假设单位圆内接多边形的边长为2b,边数为i,则边数加倍后新的正多边形的边长为:


周长为:
    y=2 * i * x        i:为加倍前的正多边形的边数

*程序与程序注释
#include<stdio.h>
#include<math.h>
void main()
{
   double e=0.1,b=0.5,c,d;
   long int i;                /*i: 正多边形边数*/
   for(i=6;;i*=2)            /*正多边形边数加倍*/
   {
      d=1.0-sqrt(1.0-b*b);     /*计算圆内接正多边形的边长*/
      b=0.5*sqrt(b*b+d*d);
      if(2*i*b-i*e<1e-15) break;         /*精度达1e-15则停止计算*/
      e=b;      /*保存本次正多边形的边长作为下一次精度控制的依据*/
   }
   printf("pai=%.15lf\n",2*i*b);       /*输出π值和正多边形的边数*/
   printf("The number of edges of required polygon:%ld\n",i);
}
*运行结果
      pai=3.141592653589794
      The number of edges of required polygon:100663296

*思考题
   请用外切正多边形逼近的方法求π的近似值。

----------------------------------------------------------------

79.求π的近似值(2)
    利用随机数法求π的近似值
*问题分析与算法设计
    随机数法求π的近似值的思路:在一个单位边长的正方形中,以边长为半径,以一个顶点为圆心,在政权方形上作四分之一圆。随机的向正方形内扔点,若落入四分之一圆内则计数。重复向正方形内扔足够多的点,将落入四分之一圆内的计数除以总的点数,其值就是π值四分之一的近似值。
    按此方法可直接进行编程,注重:本方法求出的π值只有统计次数足够多时才可能准确。
*程序与程序注释
#include<time.h>
#include<stdlib.h>
#include<stdio.h>
#define N 30000
void main()
{
    float x,y;
    int c=0,d=0;
    randomize();
    while(c++<=N)
    {
        x=random(101);      /*x:坐标。产生0到100之间共101个的随机数*/
        y=random(101);      /*y:坐标。产生0到100之间共101个的随机数*/
        if(x*x+y*y<=10000)     /*利用圆方程判定点是否落在圆内*/
            d++;
    }
    printf(" pi=%f\n",4. *d/N);    /*输出求出的π值*/
}
*运行结果
    多次运行程序,可能得到多个不同的对口果,这是因为采用的是统计规律求出的近似值,只有当统计的次数足够大时,才可能逼近π值。运行四次,可能的结果是:
        3.122267
        3.139733
        3.133733
        3.106800
上一篇:{实例}C趣味程序百例(24) 人气:5842
下一篇:{实例}C趣味程序百例(26) 人气:7307
视频教程列表
文章教程搜索
 
C语言程序设计推荐教程
C语言程序设计热门教程