从零开始学编程---第一步-C语言(十六)

时间:2014-03-06 14:37    点击:

下面我们来个难度大的,用c语言打印杨辉三角

杨辉三角大家应该知道是什么东西吧,一个奇妙的三角形,奥秘太多了

光是研究它的规律就够一阵了,但我们不是搞数学的,没必要去钻研它

这题用很多种解法,有用多维数组的,递归的,还有用组合数公式的C(m,n) =m!/((m-n)!n!) 等。。

现在我们只用我们所学的来解决这道题
先不妨试着打印这个
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1

在此之前我们先了解杨辉三角的性质
    
1、每行数字左右对称,由1开始逐渐变大,然后变小,回到1。    
2、第n行的数字个数为n个。     
3、第n行数字和为2^(n-1)。     
4、每个数字等于上一行的左右两个数字之和。可用此性质写出整个帕斯卡三角形。         
5、将第2n+1行第1个数,跟第2n+2行第3个数、第2n+3行第5个数……连成一线,这些数的和是第2n个斐波那契数。将第2n行第2个数,跟第2n+1行第4个数、第2n+2行第6个数……这些数之和是第2n-1个斐波那契数。    
6、第n行的第1个数为1,第二个数为1×(n-1),第三个数为1×(n-1)×(n-2)/2,第四个数为1×(n-1)×(n-2)/2×(n-3)/3…依此类推。


我们用第6个性质
1              第0行
1 1            第1行
1 2 1          第2行
1 3 3 1        第3行
1 4 6 4 1      第4行

每一行第一个数字是1,我们只要在循环的时候一开始就打印1就可以了
我们就只需考虑下面的数字
               第0行
1              第1行
2 1            第2行
3 3 1          第3行
4 6 4 1        第4行

前面的数字是几就代表是第几行
根据性质6 我们可以推导出运算公式 c=1 c=c*(a-b+1)/b    因为是以0行开始,所以这里要加1
下面测试一下 求第3行的所有数
第1个数 c=1*(3-1+1)/1=3
第2个数 c=3*(3-2+1)/2=3
第3个数 c=6*(3-3+1)/3=1

测试正确,公式成立
下面运用于循环中

设3个变量 a,b,c
a控制行循环 b控制行的数循环(列循环),c显示数字

首先是a循环 打印5行
for (a=0;a<=4;a++) 从0行开始
然后是列循环,从某行的第一数开始循环,行多少就循环多少个数字,自然不能大于行
for (b=1;b<=a;b++) 


现在程序就出来了
#include <stdio.h>
main()
{
        int    a,b,c;

        for (a=0;a<=4;a++)
        {
            c=1;
            printf("%d",c);
            for     (b=1;b<=a;b++)   
            {   
                c=c*(a-b+1)/b;

printf("%5d",c);   
            }   
            printf("\n");   
      }


}

a循环每一开始就会自动打印1


这个程序就可以打印三角形了,换了种形式写,比较复杂,公式是分开写的,应该容易看懂
#include <stdio.h>
main()
{
         int a,b,c,x,y;
         for(a=0;a<5;a++)
         {
             for(b=5;b>a;b--)
                 printf(" ");
             for(b=0;b<=a;b++)
             {
                 x=y=1;
                 if(b>=1)
                 {
                     for(c=a-b+1;c<=a;c++)
                         x*=c;
                     for(c=1;c<=b;c++)
                         y*=c;
                 }
                 printf("%d",x/y);
                 printf(" ");
             }

   printf("\n");
         }

}

另一种形式,其实都大同小异
#include <stdio.h>
main()
{
         int a,b,c,x,y;
         for(a=0;a<5;a++)
         {
         for(b=0;b<=a;b++)
         {
         if(b==0||b==a)
         printf("%6d",1);
         else
         {
         long x=1,y=1;
         for(int c=1;c<=b;c++)
         {
           x=x*c;
           y=y*(a-c+1);
         }
         printf("%6d",y/x);
         }
         }
         printf("\n");
         }



}


输入n数的程序
#include <stdio.h>
main()
{
       long a,b,n,c;
       printf("请输入一个数:");
       scanf("%ld",&n);
       for(a=1;a<=n;a++)
       {
        c=1;
        for(b=1;b<=n-a;b++)
           printf(" ");
       for(b=1;b<a;b++)
       {
       printf("%ld ",c);
       c=c*(a-b)/b;
       }
       printf("1\n");
       }



}

注意这里行从1开始,所以c=c*(a-b)/b; 不需要+1



提醒,这一题实在看不懂可以略过,别去钻牛角尖,可以放着以后去弄懂


下面我们用循环打印空心三角形


题目不难,关键你的逻辑能不能想到那里去

现在我们分析
首先行循环,和左边空格循环是肯定要的

我把空格用#标记出来
###*---------------------1行
##*#*--------------------2行
#*###*-------------------3行
*******------------------4行

外层空格循环你们是知道做的,里层循环怎么做
看上面你会发现
第1行,里层没有空格要打
第2行 打一个空格
第3行 打3个空格
第4行 本来是5个空格,但是因为是最后一行所以是5个*号


1----0
2----1
3----3
4----5
规律出来了,数列公式为 2*a-3
*号要循环吗,不需要
我们只要在外层空格循环之后打印一个*号,然后里层空格循环之后在打印一个*号就可以了

注意,第一行只打印一个*号,怎么去控制应该知道吧
下面是程序

#include <stdio.h>
main()
{
       int    a,b,c;
     

       for(a=1;a<=4;a++)
       {
           for(b=1;b<=4-a;b++)
           {
               printf(" ");
             
           }
           if(a>1)            //大于1的打印*,也就是除了第一行都打印一个*
           printf("*");
           for(c=1;c<=2*a-3;c++)
           {
             
               if(a==4)      //如果等于最后一行,把空格替换成*
               printf("*");
               else
               printf(" ");
             
           }
           printf("*");
           printf("\n");
       }

     

}


要打个空心的菱形你们应该也会吧
###*
##*#*
#*###*
*#####*
#*###*
##*#*
###*

下部分只有3行
里层空格
1-----3个
2-----1个
3-----0个

数列公式就是5-2*a



程序如下
#include <stdio.h>
main()
{
       int    a,b,c;
     

       for(a=1;a<=4;a++)
       {
           for(b=1;b<=4-a;b++)

{
               printf(" ");
             
           }
           if(a>1)            //大于1的打印*,也就是除了第一行都打印一个*
           printf("*");
           for(c=1;c<=2*a-3;c++)
           {
               printf(" ");
             
           }
           printf("*");
           printf("\n");
       }

       for(a=1;a<=3;a++)
       {
           for(b=1;b<=a;b++)
           {
               printf(" ");
           }
           printf("*");
           for(c=1;c<=5-2*a;c++)
           {
               printf(" ");
           }
           if(a==3)     //如果是最后一行,就只输出一个空格,不再输出*号
           printf(" ");
           else
           printf("*");
         

           printf("\n");

       }

     

}



输入一个数n打印n大小的空心菱形也会把,程序如下
#include <stdio.h>
main()
{
       int    a,b,c,n;
       printf("请输入一个数:");
       scanf("%d",&n);
     

       for(a=1;a<=n;a++)
       {
           for(b=1;b<=n-a;b++)
           {
               printf(" ");
             
           }
           if(a>1)         
           printf("*");
           for(c=1;c<=2*a-3;c++)
           {
               printf(" ");
             
           }
           printf("*");
           printf("\n");
       }

      for(a=1;a<=n-1;a++)
       {
           for(b=1;b<=a;b++)
           {
               printf(" ");
           }
           printf("*");
           for(c=1;c<=2*n-3-2*a;c++)
           {
               printf(" ");
           }
            
               if(a==n-1)
                   printf(" ");
               else
                    printf("*");
           printf("\n");
       }
     

}

    for(c=1;c<=2*n-3-2*a;c++)
这里

4行的时候是5-2*n
5行的时候是7-2*n

你可以推导了

1-----0
2-----1
3-----3
4-----5

所以是2*n-3-2*a




来源:幻想编程//所属分类:站长原创/更新时间:2014-03-06 14:37
顶一下
(6)
100%
踩一下
(0)
0%
上一篇:从零开始学编程---第一步-C语言(十五)
下一篇:从零开始学编程---第一步-C语言(十七)
相关内容