これ、詰まる人には詰まると思う。二次元配列の添字の扱いに習熟していないと難しい。
問題概要
のグリッドが与えられる。各マス目には 0 か 1 の値が書かれている。
このグリッドに対して、外周を時計回りに 1 マス分回して得られるグリッドを答えよ。
考えたこと
二次元配列における各マスの添字の扱いの習熟度が十分ないと、難しく感じたのではないかと思う。なお、上から 行目、左から
列目のマスを
と書くことにする。0-indexed で考えることにするので、たとえば左上のマスは
となり、右下のマスは
となる。
この問題を解く方針はいろいろ考えられるが、ここでは、
- 答えとなる
のグリッドを用意する
- 答えとなるグリッドの各マス
が、もとのグリッド
のどのマスに対応するかを整理する
という方針で考えることにした。具体的には次のコードのようになる。
#include <bits/stdc++.h> using namespace std; int main() { int N; cin >> N; vector<string> A(N); for (int i = 0; i < N; ++i) cin >> A[i]; // 答えの (i, j) マスを順に調べていく vector<string> res(N, string(N, '0')); for (int i = 0; i < N; ++i) { for (int j = 0; j < N; ++j) { if (i == 0 && j >= 1) { // (0, 1), (0, 2), ..., (0, N-1) は左からとってくる res[i][j] = A[i][j-1]; } else if (i >= 1 && j == N-1) { // (1, N-1), (2, N-1), ..., (N-1, N-1) は上からとってくる res[i][j] = A[i-1][j]; } else if (i == N-1 && j < N-1) { // (N-1, 0), (N-1, 1), ..., (N-1, N-2) は右からとってくる res[i][j] = A[i][j+1]; } else if (i < N-1 && j == 0) { // (0, 0), (1, 0), ..., (N-2, 0) は下からとってくる res[i][j] = A[i+1][j]; } else { // 外周以外はそのままとってくる res[i][j] = A[i][j]; } } } // 出力 for (int i = 0; i < N; ++i) cout << res[i] << endl; }