1. 程式人生 > >關於C語言列印菱形的各種題型

關於C語言列印菱形的各種題型

在做一些列印菱形的題目時發現題型不外乎這幾種:

【一】:輸出*形組成的菱形

①題目:

            描述

由鍵盤輸入正數n(n<30,n為奇數),要求輸出具有n行的如下圖案。

            輸入樣例

7

            輸出樣例

*******
*** ***
**   **
*     *
**   **
*** ***
*******
凡是遇到這種輸出幾就有幾行的菱形(例如n=7,則有7行),一般採取“對稱法”,就是設一個for迴圈
<span style="white-space:pre">		</span>for(i=-(n/2);i<=n/2;i++)
這個i就是用來控制行,而且上下對稱,例如第二行和倒數第二行的時候i的絕對值相同,就可以通過這個相同的絕對值來輸出相同個數的*和空格,具體操作程式碼如下:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main()
{
    int n,i,j;
    scanf("%d",&n);
    for(i=-(n/2);i<=n/2;i++)
    {
        if(i==-(n/2)||i==(n/2))
        {
            if(i==-(n/2))
            {
                for(j=1;j<=n;j++)
                {
                    printf("*");
                }
                printf("\n");
            }

            else
            {
                for(j=1;j<=n;j++)
                {
                    printf("*");
                }
            }
        }
        else
        {
            for(j=1;j<=abs(i)+1;j++) printf("*");
            for(j=1;j<=(n-2*(abs(i)+1));j++) printf(" ");
            for(j=1;j<=abs(i)+1;j++) printf("*");
            printf("\n");
        }
    }
    return 0;
}
②還有別的情況就是輸入的n不是代表行數,而是其它數字,例如下面這道題:

Description

由鍵盤輸入正數n(n<30),要求輸出如下2*n+1行的菱形圖案。

輸出格式

菱形右邊不留多餘空格

輸入樣例

2

輸出樣例

  *
 ***
       *****
***
  *
這道題是輸入一個n,則輸出2*n+1行的*,其實思路是一樣的,還是利用i的絕對值相同上下對稱的原理,只需要改變一下i與n的關係,具體程式碼如下:
#include "stdio.h"
#define abs(x) ((x)>0?(x):-(x))
main()
{   
   int n,i,j;
   scanf("%d",&n);
   for(i=-n;i<=n;i++)
   {
        for(j=1;j<=abs(i);j++)  printf(" ");
        for(j=1;j<=2*n+1-2*abs(i);j++)  
        printf("*");
        printf("\n");
   }
}

還有一種情況是輸入一個n,則輸出2*n-1行的*,思路更是差不多,這裡就不累述了。但還有一種情況要提一下,就是下面的第3種。
③這種情況是輸出半邊的菱形。
如:編寫程式,輸入整數n,輸出n行的字元圖案。例如n=5時輸出:
    *
   **
   ***
  ****
  *****
  ****
   ***
   **
    *

輸入格式
輸入一個整數

輸出格式
輸出2*n-1行的三角形

輸入樣例
2

輸出樣例
 *
 **
 *
分析:這種情況需要我們先輸出空格然後輸出*,所以我們應該找到空格、*與i的關係,不難發現每一行的空格和*的和都等於n,那麼我們只需要控制i設定一個迴圈就行了。
#include <stdio.h>
#include <stdlib.h>

int main()
{
    int n;
    scanf("%d",&n);
    int hang=n*2-1;
    int i,kong,tmp,i_;
    for(i=1;i<=hang;i++)
    {
        if(i<=n)
        {
            kong=n-i;
            for(;kong>0;kong--)
            printf(" ");
            tmp=i;
            while(tmp>0)
            {
                printf("*");
                tmp--;
            }
            printf("\n");
        }
        else
        {
            i_=hang+1-i;
            kong=n-i_;
            for(;kong>0;kong--)
            printf(" ");
            tmp=i_;
            while(tmp>0)
            {
                printf("*");
                tmp--;
            }
            printf("\n");
        }
    }
    return 0;
}
以上大概就是*型別的菱形列印題型,然而題目的做法遠遠不止這些,本人還找到了一些更新奇的做法,在這裡和大家分享一下!
方法一、根據圖形的樣子找出規律,如下圖:
列印菱形程式如下:
在圖形中畫十字分成4份,以其中的一部分考慮
#include 
#define M 3  /*可以自定義菱形的大小*/
int main(int argc, char** argv)
{
    int i,j,k;
    for(i=0;i<=M;i++)/*上半部分的行數*/
    {
        for(j=0;j<=M-1-i;j++)/*列印空格的個數,我是以0開始的*/
        printf(" ");
        for(k=0;k<=2*i;k++)/*,假如除去空格外都列印“*”,則以2*i+1列印"*"個數,這是每一行的特點*/
        {
            if(k==0||k==2*i)/*然後只選擇你要列印的“*”位置的個數*/
            printf("*");
            else
            printf(" ");/*之間的全為空格*/
        }
    printf("\n");
    }
    for(i=0;i<=(M-1);i++)/*下半部分比上班部分少一行*/
    {  
        for(j=0;j<=i;j++)
        printf(" ");
        for(k=0;k<=2*(M-1)-2*i;k++)/*判斷k時沒有合併式子,僅供學習探究,這點判斷很重要,留作你自己思考了*/
        {
            if(k==0||k==2*(M-1)-2*i)/*同上分析*/
            printf("*");
            else
            printf(" ");
        }
        printf("\n");
    }
    return 0;
}
方法二、擴充套件思想,把它當作正方形中擷取的圖形如下圖:
#include 
#include 
#include 
#define M 3
int main()
{
    int i,j;
    for(i=-M;i<=M;i++)
    {
        for(j=-M;j<=M;j++)
        if((abs(i)+abs(j))==M)       /*橫縱座標之和等於M的則全部列印*/
        printf("*");
        else
        printf(" ");
        printf("\n");
    }
    getch();
    return 0;
}
這個方法看起來很簡單易懂,但是演算法巧妙。覺得是一個很好的思想。至此,當然你開可以發揮讓它列印實體的菱形了,怎麼打?還是看規律,發現橫縱座標之和只要小於等於M就讓它列印,修改程式碼為if((abs(i)+abs(j))<=M) 即可。還可以發揮思想看怎樣修改可以列印如下的圖案:
         a
       bcd
      efghi
   gklmnop
      qrstu
       vwx
         y
下面來討論一下第二大類,數字類的菱形。
【二】輸出數字類的菱形
這種型別的題目可以變化的範圍就很大了,題目五花八門,這裡給出下面一些例子。

Description

由鍵盤輸入正數n(n<10),要求輸出如下中間數字為n的菱形圖案。

輸出格式

菱形右邊不留多餘空格

輸入樣例

        4

輸出樣例

        1
           121
         12321
       1234321
         12321
          121
        1
這種和上面的第一大類的第2小類很類似,但需要多考慮數字的變化,最簡潔的版本是下面這個。
#include<stdio.h>
#define abs(x) ((x)>0?(x):-(x))
main()
{   
    int n,i,j;
    scanf("%d",&n); 
    n--;
    for(i=-n;i<=n;i++)
    {   
        for(j=0;j<abs(i);j++) printf(" ");
        for(j=-(n-abs(i));j<=n-abs(i);j++) 
        printf("%d",n+1-abs(j)-abs(i));
        printf("\n");
    }
}
但本人第一次做這道題的時候實在想不出這種方法,所以我的做法是下面這個:
#include <stdio.h>
#include <stdlib.h>

int main()
{
    int i,k,j;
    int n;
    scanf("%d",&n);
    int hangshu=n*2-1;
    int tmp=n;
    int d=1;

    for(i=1;i<=hangshu;i++)
    {
        k=tmp-1;
        if(k<0)
        k=-k;
        while(k>0)
        {
            printf(" ");
            k-=1;
        }
        tmp-=1;

        if(i<=n)
        {
            int geshu=i*2-1;
            int a;
            int b=1;
            for (a=1;a<=geshu;a++)
            {
                if(b>i)
                {
                    int c=b;
                    int d;
                    if(b-i==1)
                    d=1;
                    c=c-d*2;
                    printf("%d",c);
                    d+=1;
                    b+=1;
                    continue;
                }
                printf("%d",b);
                b+=1;
            }
        }
        else
        {
            int geshu=(i*2-1)-4*(i-n);
            int a;
            int b=1;
            for(a=1;a<=geshu;a++)
            {
                if(b>(i-2*(i-n) ))
                {
                    int c=b;

                    c=c-d*2;
                    printf("%d",c);
                    d+=1;
                    b+=1;
                    continue;
                }
                printf("%d",b);
                b+=1;
            }

         d=1;
        }
    printf("\n");
    }
    return 0;
}
但不管是哪種方法,其實關鍵都是要找到一個函式關係式能滿足行數與輸出數字個數的關係,這個你只能慢慢研究。
類似的題型還有很多,以後會再補充,也歡迎大家來評論補充。