ID非公開

2020/8/8 12:55

44回答

1 2 3 4 12 13 14 5 11 16 15 6 10 9 8 7 上のような二次元配列を作りたいです。4x4だけでなく1x1や500x1000(上限は1000)にも対応したいです。皆さんならどのように実装しますか?一番綺麗なコードを書いた人にベ

1 2 3 4 12 13 14 5 11 16 15 6 10 9 8 7 上のような二次元配列を作りたいです。4x4だけでなく1x1や500x1000(上限は1000)にも対応したいです。皆さんならどのように実装しますか?一番綺麗なコードを書いた人にベ ストアンサーを差し上げます。回答よろしくお願いします。

補足

アルゴリズムを見たいのでプログラミング言語の種類は問いません。

ベストアンサー

1

最近見たところでは https://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q10229228330 とか https://teratail.com/questions/264036 とか。 https://teratail.com/questions/280509#reply-399241 はそのままだと正方にしか対応してないか。

1人がナイス!しています

ThanksImg質問者からのお礼コメント

皆様回答ありがとうございました!

お礼日時:8/10 8:48

その他の回答(3件)

0

数字の進む方向に空きがあれば数字を書き込みます。 配列の領域外や既に数字が書き込まれていれば右に曲がって進むというアルゴリズムです。 C++です。 #include <iostream> #include <iomanip> #include <vector> using namespace std; struct DirC {     int r; // 行方向。-1:上へ、0:変化なし、1:下へ。     int c; // 列方向。-1:左へ、0:変化なし、1:右へ。 }; class SpiralC { public:     vector<int> ary;     int rows; // 行(縦)のサイズ     int cols; // 列(横)のサイズ     int r = 0; // 数字の現在の行位置     int c = -1; // 数字の現在の桁位置。あらかじめ1を引きます     int num = 1; // 数字     DirC rc{0, 1}; // 数字の進む方向     SpiralC(int _rows, int _cols) : rows(_rows), cols(_cols), ary(_rows*_cols) {}     void dsp() const {         int _c = 0;         for (const auto &e : ary)             cout << (rows*cols >= 100 ? setw(3) : setw(2)) << e << (++_c%cols ? ' ' : '\n');     }     bool if_walk() {         int tr = r+rc.r;         int tc = c+rc.c;         if (0 <= tr && tr <= rows-1 && 0 <= tc && tc <= cols-1) {             if (ary[tr*cols+tc] == 0) {                 r = tr;                 c = tc;                 ary[r*cols+c] = num++;                 return true;             }             else                 return false;         } else             return false;     }     void make() {         for (;;) {             if (!if_walk()) {                 // rc.r  0  1   0  -1                 // rc.c  1  0  -1   0                 rc = {rc.c, -rc.r};                 if (!if_walk()) break;             }         }     } }; int main() {     int rows, cols;     cout << "行サイズ > "; cin >> rows;     cout << "列サイズ > "; cin >> cols;     SpiralC sp(rows, cols);     sp.make();     sp.dsp(); }

1

https://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q10229228330 における はらがくろいこさん のアルゴリズムはいかがでしょうか? こちらのアルゴリズムを Python で実装するとこんな感じです。 dirs = [[0, 1], [1, 0], [0, -1], [-1, 0]] size = int(input()) lst = [[0] * size for _ in range(size)] idx, row, col = 0, 0, 0 side = size i = 0 while i < size * size:   for _ in range(side):     row += dirs[idx][0] if i > 0 else 0     col += dirs[idx][1] if i > 0 else 0     i += 1     lst[row][col] = i   idx = (idx + 1) % len(dirs)   if dirs[idx][0]:     side -= 1 max = len(str(size * size)) for i in range(size):   for j in range(size):     print(f'{lst[i][j]:{max}d}', end=' ')   print()

1人がナイス!しています

ID非公開

質問者

2020/8/8 18:01

回答ありがとうございます! なるほど。一方向に進む距離をあらかじめ計算しておいて、その分だけ一気に進むと…。ただ、sideの初期値をどうするかとsideの値をいつ減らすかを考える必要があるので、空で書こうとするとバグらせてしまいそうです。長方形のときは特に…。 最大値の桁数を求めるときに文字列に変換する発想はなかったので参考になります。ありがとうございます!