1. 程式人生 > 其它 >PTA自測-1 列印沙漏

PTA自測-1 列印沙漏

目錄

題目

本題要求你寫個程式把給定的符號列印成沙漏的形狀。例如給定17個“*”,要求按下列格式列印

*****
 ***
  *
 ***
*****

所謂“沙漏形狀”,是指每行輸出奇數個符號;各行符號中心對齊;相鄰兩行符號數差2;符號數先從大到小順序遞減到1,再從小到大順序遞增;首尾符號數相等。

給定任意N個符號,不一定能正好組成一個沙漏。要求打印出的沙漏能用掉儘可能多的符號。

輸入格式: 輸入在一行給出1個正整數N(≤1000)和一個符號,中間以空格分隔。

輸出格式: 首先打印出由給定符號組成的最大的沙漏形狀,最後在一行中輸出剩下沒用掉的符號數。

輸入樣例: 19 * 輸出樣例:

*****
 ***
  *
 ***
*****
2

因為前幾次提交的時候有格式錯誤,看了別人的提醒才知道要注意:
每一行輸出完符號後,它後面是沒有空格的!!!空格只能前面有空格,後面不能有!!!
還有就算沒有剩餘的符號也要輸出0。

程式碼思路

這裡是先建立一個奇數陣列,為什麼建立奇數陣列?因為在陣列下標為0,元素為1,則20+1=1,下標為1,元素為3,則21+1=3......以此類以,用下標作為一邊需要輸的行數。如下圖所示:

然後輸入的符號個數減去1,減去的1是沙漏中間只有一個符號的那一行,剩下的除2平分掉,相對於把沙漏上下平分掉,因為除去了中間那一個,上下部分是一樣數目的。並且一定要算出有沒有餘數,餘數是要算在剩餘字元數量裡的。如19個字元,出去中間部分,19-1=18,然後平分,18/2=9,餘數為0,兩邊各自的符號數量為9。如果數目為20,20-1=19,19/2=9,餘數為1,餘數要加在剩餘符號數量裡。

然後算出一邊的數目後,這個數目和奇數陣列從0開始一直比較,當奇數陣列的元素小於或等於這個數目,則該數目就等於該數目減去元素,再接著與下一個元素比較,以此類推,最後元素大於該數目,則剩下的該數目就為剩餘的數的一部分。

程式碼

#include <stdio.h>
void print_top(int num[],int i,char zf);
void print_bottom(int num[],int i,char zf);
int main(void)
{
    int n;                                                                              
    int num[1000];
    int shu,shu1;
    char zf;
    int i;
    //設定奇數表,根據下標來取對應的元素來決定上半部分or下半部分要輸出多少行
    for(n=0;n<1000;n++){
        num[n]=2*n+1;
    }
    //輸入兩個數
    scanf("%d %c",&shu,&zf);
    //算出除了中間一個,兩邊各自的數量
    shu1 = (shu-1)/2;
    //迴圈每個奇數與shu1比較
    for(i=1;num[i]<=shu1;i++){
        shu1 = shu1-num[i];     //shu1位一邊剩餘的數
    }
    if(shu!=0 && (shu-1)%2==0){
        print_top(num,i-1,zf);
        print_bottom(num,i-1,zf);
        printf("%d",shu1*2);        
    }else if(shu!=0 && (shu-1)%2!=0){
        print_top(num,i-1,zf);
        print_bottom(num,i-1,zf);
        printf("%d",shu1*2+((shu-1)%2));          
    }

    return 0;
}
void print_top(int num[],int i,char zf)//列印上部分
{
    int j,k,x;
    //i為從傳過來的i-1列印最多字元的下標
    for(j=i;j>=0;j--){  //根據下標來輸出多少行
        if(j!=i){   //當j不為最多符號那一行
            for(x=j;x<i;x++){   //列印空格
                printf(" ");
            }
        }
        for(k=0;k<num[j];k++){  //根據該下標的元素值來決定列印多少次符號
            printf("%c",zf);
        }
        printf("\n");
    }
}
void print_bottom(int num[],int i,char zf)//列印下部分
{
    int j,k,x;
    for(j=1;j<=i;j++){
        if(j!=i){
            for(x=j;x<i;x++){
                printf(" ");
            }
        }
        for(k=0;k<num[j];k++){
            printf("%c",zf);
        }
        printf("\n");
    }
}