• ベストアンサー

アルゴリズムについて

整数nが与えられたとき、n×nのサイズで螺旋状に 0から(n×n-1)までの数字が並ぶ行列を作成し、 画面に表示するようなプログラムを教えてください。 出力するとこんな感じに表示されると思います。 n=4のとき 0 1 2 3 11 12 13 4 10 14 15 5 9 8 7 6

質問者が選んだベストアンサー

  • ベストアンサー
回答No.1

   一応できたので。 #include <stdio.h> #include <stdlib.h> int main(void) { int num, x, y, current, curr_top, i; int **square; scanf("%d", &num); if((square = (int **)malloc(num * sizeof(int *))) == NULL){ puts("Alloc Error"); } for(i = 0; i < num; i ++){ if((*(square + i) = (int *)malloc(num * sizeof(int))) == NULL){ puts("Alloc Error"); } } for(curr_top = current = 0; current < (num + 1) / 2; current ++){ x = y = current; square[x][y] = curr_top; for(i = 1; i < (num - 2 * current - 1) * 4; i ++){ if(y == current && x < num - current - 1) x ++; else if(x == num - current - 1 && y < num - current - 1) y ++; else if(y == num - current - 1 && x > current) x --; else if(x == current && y > current) y --; square[x][y] = curr_top + i; } curr_top += i; } for(y = 0; y < num; y ++){ for(x = 0; x < num; x ++){ printf("%2d ", square[x][y]); } putchar('\n'); } return 0; }  

その他の回答 (2)

  • yukimican
  • ベストアンサー率70% (112/159)
回答No.3

#1さんではありませんが。 要は、n×nの行列に対して 「左上から螺旋状に数字を埋めていく」 というのを忠実に実行しています。 例えば、4x4の行列だと 左上(square[0][0])→右上(square[3][0]) →右下(square[n][3])→左下(square[0][3]) →左上(square[0][1]) の順に1周すると、内側に2x2の行列が残ります   0  1  2  3  11 × ×  4  10 × ×  5   9  8  7  6 それに対して、また 左上(square[1][1])→・・・と繰り返すわけです。 そうすると、   0  1  2  3  11 12 13  4  10 14 15  5   9  8  7  6 という感じで行列が埋まっているので、 1行目から順番に出力すればいいわけですね。 上を念頭に置いてソースをじっくり読めば やっていることがわかると思います。

blackandfly
質問者

お礼

説明ありがとうございます! ようやく理解できました。 ただmallocはよくわからなかったので int square[100][100]に置き換えました。 お二人とも本当にありがとうございました。 もしかしたらまたお世話になるかもしれませんw

回答No.2

   最後の表示部分を、 temp = num * num - 1; for(i = 0; temp / 10 > 0; i ++) temp /= 10; for(y = 0; y < num; y ++){ for(x = 0; x < num; x ++){ printf("%*d ", i + 1, square[x][y]); } putchar('\n'); } に変更。  

blackandfly
質問者

お礼

すごい!ありがとうございます! あと、もしよろしければプログラムの仕組みについて 説明して頂けないでしょうか? よろしくお願いします。

関連するQ&A

  • アルゴリズム

    教えてください。 フローチャート作成 入力された10進の自然数xを2進数yに変換し出力するプログラムのフローチャートをサブルーチンも含めて全て書け。ただし、整数型の変数aから第iビット目(最初を下位ビットとして第0ビットとせよ)を取り出す整数型関数(メソッド)get_bit( a,i )を作成すること。 プログラム作成 上で設計したプログラムを作成する。 実行結果 上で作成したプログラムの実行し、その実行結果を示す。

  • アルゴリズム

    教えてください フローチャート作成 キーボードから自然数nを入力し、1からnまでの和を求め、出力するプログラムのフローチャートをサブルーチンも含めて全て書く

  • アルゴリズムのフローチャート(ヒストグラム)

    0以上10以下の整数を入力として繰り返し受けつけ、階級の幅が3であるようなヒストグラムを出力する。 終了記号は-1とする。     始     ↓    i←0 ↑→→↓ ↑  X[i]←0 ↑   ↓ ↑←←i≧4  NO ↓     ↓YES     ↓    入力:N     ↓ ↑→→↓YES ↑   ↓ ↑  N=-1 →YES→出力:X→終 ↑   ↓ ↑   ↓NO ↑   ↓ ↑  N←N/3 ↑   ↓ ↑  X[N]←X[N]+1 ↑   ↓ ↑←←↓ 見にくい図で申し訳ありません。 このようなフローチャートがあるのですが、全体の流れの意味がよくわかりません。 特に後半の「N←N/3」以降はどういった意味なのでしょうか? よろしければ解説をお願い致します。

  • 順列生成アルゴリズムについて仕組みを教えてください

    ある本を参考に順列を出力するプログラムをJavaScript用に書き直しました。 上手く動いたのですが、どうして、順列を出力できるのか理解できません。 まず、プログラムは以下になります。 <script> // 対象の配列 var array = [0,1,2,3]; // 配列の数 var N = array.length; // 順列を出力するプ関数 function permutation( n ) { // テンポラリー用 var temp; // 順列を生成する処理部分 if ( n < N ) { for ( var i = n; i < N; i++ ) { // (1)対象の配列から数字を一つ取り出して、他の数字と入れかえる temp = array[n]; array[n] = array[i]; array[i] = temp; // (2)再起呼び出し permutation( n + 1 ); // (3)入れ替えた数字を元に戻す temp = array[n]; array[n] = array[i]; array[i] = temp; } } else { // 出力 console.log( "結果:" + array); } } // エントリーポイント permutation(0); </script> 処理を理解するために、コメントの(1)や(3)などに console.log を入れて、出力したところ、全く理解できないスタックの流れになっていました。 具体的には、1~2を条件を満たす間繰り返した後、一度出力(スタック開放)します。その後、(3)の処理をするのですが、その直ぐ後に、また(3)の処理をするのです。 具体的なログは以下のようになりました。 【n=0】**************************// 関数の呼出しと呼出し時の引数です。 i=0  再帰前:1回:0,1,2,3 n=0      // (1)の処理です。0,1,2,3は、対象の配列です。 【n=1】************************** i=1  再帰前:2回:0,1,2,3 n=1 【n=2】************************** i=2  再帰前:3回:0,1,2,3 n=2 【n=3】************************** i=3  再帰前:4回:0,1,2,3 n=3 【n=4】************************** スタック開放:0,1,2,3 n=4   再帰後:1回:0,1,2,3 n=3     // (3)の処理です。   再帰後:2回:0,1,2,3 n=2     // なぜ連続して呼ばれているのか i=3  再帰前:5回:0,1,3,2 n=2 【n=3】************************** i=3  再帰前:6回:0,1,3,2 n=3 【n=4】************************** スタック開放:0,1,3,2 n=4   再帰後:3回:0,1,3,2 n=3   再帰後:4回:0,1,2,3 n=2     // なぜ連続して呼ばれているのか   再帰後:5回:0,1,2,3 n=1     // なぜ連続して呼ばれているのか i=2  再帰前:7回:0,2,1,3 n=1 【n=2】************************** “なぜ連続して呼ばれているのか”の部分が理解できません。予想では、再帰後の部分が一度呼ばれて、このプログラムは止まってしまうと思うですが、最後まで動きます。 なぜ、止まらずに動くのか教えてください。

  • n✕n行列(非対称)の固有値問題のアルゴリズム

    よろしくおねがいします。 タイトルの通り、 n✕n行列の固有値を求めるプログラムを作成しようと考えています。 ただし、行列は非対称行列とするためJacobi法等は使えません。 そこで、 このプログラムを作成する際の一般的なアルゴリズムを教えていただきたいです。 例えば、どういった法則を使うのか?などです。 具体的であればあるほどありがたいです。 しょぼい質問ですがお願いします。

  • c言語プログラミングの質問です。

    整数NとN個の整数を受け取り,受け取ったN個の整数のうち最大のものを表示するプログラムを記述せよ. ただし,N>0とする. 入出力例 入力 ⇒ 出力 3 2 1 8 ⇒ 8 5 13 14 11 12 15 ⇒ 15 2 -1 -2 ⇒ -1 という問題です。「3つの数の中から~」という場合はそれぞれa,b,cとおいて比較できるのですが、この問題のような場合はどうすればいいですか。

  • "n!"(階乗)の数字列の生成

    ある"n"(数字)を入力すると、"n!"(階乗)通りの数字列を生成するプログラムを作りたいのですが、 どのような考え方でプログラムを作成すればよいのかわかりません。 例えば、"7"と入力すると 1,2,3,4,5,6,7 1,2,3,4,5,7,6 1,2,3,4,6,5,7    ・    ・    ・ 7,6,5,4,3,2,1 のように7!通りの数字列を出力されるようにしたいのです。 アドバイスを頂けないでしょうか。よろしくお願いします。

  • forループ

    C語課題で出されたのですが forをつかって正の整数nをキーボードから入力し, nに応じて「*」で模様を描くプログラムを作成せよ。 (nは50まで対応させる) n=1 n=2 n=3  ・・・n=50 *   **  ***      **  ***           *** といったように表示させたいのですが、 50まで対応するようにする方法がわかりません。 教えてください。

  • C言語のプログラミング (基礎)配列の問題ですが。

    次のような問題があって、プログラミングしてみたのですが、 コンパイルすると永久ループになってしまいます。 また、入力されるはずの整数が表示されません。 どうすればよいか教えていただけると助かります。 よろしくお願いします。 整数を順番に入力し、負の数が入力されたら、それまでに入力された非負の整数を、 入力された順番とは逆に全角空白で区切って出力するプログラムを作成しなさい。 自動評価の都合上、上記以外は表示しないこと。なお、入力は最大10回とする。 【0 1 2 3 4 -1 が入力された場合の表示例】 4 3 2 1 0       ************************************** #include <stdio.h> int main(void) { int num[10]; int n; for(n=1;n<11;n++){ printf("整数入力:¥n"); scanf ("%d", &num[n]); if(num[n]<0){ for(n=10;n>0;n--){ printf("%d ",num[n]); } } } }

  • C++でのアルゴリズム

    次の条件を満たすアルゴリズムをC++のコードで教えてください! 大きさ2×1の長方形n個を 縦2 横n の長方形になるように並べるときの並べ方の総数を求めるアルゴリズム 入力nは、1以上の整数が入力される前提でよい。 例として、 n=1 1通り n=2 2通り n=3 3通り n=5 8通り n=7 21通り となります お願いします。

専門家に質問してみよう