砂時計の印刷-アルゴリズム


プリント砂時計
タイトル
文字通り、 を出力するのですが、砂時計とは何か、次のようなものです
  *****
   ***
    *
   ***
  *****

つまり、n個の*をください.この砂時計の各行の記号の数は奇数なので、規則的です.
入力例
19//記号数*
出力例
  //       
  *****
   ***
    *
   ***
  ***** 
  2 //           

問題を解く構想.
この解題の構想は私がネット上で見たので、彼はこの砂時計を像化して、*号は座標で表示して、それでは上の例は
  (0,0)(0,1)(0,2)(0,3)(0,4)
         (1,1)(1,2)(1,3)
                (2,2)
         (3,1)(3,2)(3,3)
  (4,0)(4,1)(4,2)(4,3)(4,4)

そうすると、観察を続けてみると、上下に二つ折り、左右に二つ折りして下のようになっています
  (0,0)(0,1)(0,2)
         (1,1)(1,2)
                (2,2)

何が見つかりましたか、列>=行、次に左右対称、上下対称
        >    / 2         ,        =     -      - 1,          3 = 5 - 3 -1 = 1        3        1     。

列も同じです.列数=行数なので
        >    / 2         ,        =     -      - 1,          3 = 5 - 3 - 1 = 1       3        1     。

もちろん、真ん中の行には対称性はありません
コード#コード#
次は私がphpで実現したコードで、どんな言語でも大同小異です.

  function test($count, $symbol)
    {
        $maxRow = 1; //         
        $maxCount = 1; //           
        //                         
        if ($count < $maxCount) {
            printf($count);
        } else {
            //                           
            while (true) {
                //    
                //       =       +         ((   + 2)        ,          ,   * 2)
                $nextCount = ($maxRow + 2) * 2 + $maxCount;
                //        
                if ($count < $nextCount) {
                    break;
                } elseif ($count == $nextCount) {
                    //            
                    $maxRow += 2;
                    $maxCount = $nextCount;
                    break;
                } else {
                    //                   
                    $maxRow += 2;
                    $maxCount = $nextCount;
                }

            }
            //    
            for ($i = 0; $i < $maxRow; $i++) {
                //     
                $row = $i; //   
                //           ,        ,     
                if ($i > $maxRow / 2) {
                    $row = $maxRow - $row - 1;
                }
                for ($j = 0; $j < $maxRow; $j++) {
                    //     
                    $col = $j;
                    //          
                    if ($col > $maxRow / 2) {
                        $col = $maxRow - $col - 1;
                    }
                    //       <    
                    if ($col < $row) {
                        //                         
                        if ($j > $maxRow / 2) {
                            printf("
"
); break; } else { printf(" "); } } else { // > printf($symbol); } // = if ($j == $maxRow - 1) { printf("
"
); } } } // printf($count - $maxCount); } }

参考資料
私はただ少し変更して、最小は1つの*を使って、いくつかの変数の使用上の微調整の下の原文c言語のリンクを使います
https://blog.csdn.net/hcy2319964421/article/details/53103641