はじめに
二次元配列を扱うとき、配列の作成から特定の順序での走査、さらに効率的な合計計算まで一連の操作がよく出てきます。
この記事では、C++での「二次元配列の作成」「うずまき走査(スパイラル順走査)」「累積和の作り方」をわかりやすく解説します。
配列に関してはわかりにくかったら紙に書くとわかりやすいですね!!
1. 二次元配列の作成
C++の標準ライブラリvectorを使うと簡単に動的な二次元配列を作成できます。
#include <vector>
using namespace std;
int main() {
// 3行3列の二次元配列を初期化(すべて0で埋める)
//配列の中に配列を入れているので二次元配列が完成します。
vector<vector<int>> grid(3, vector<int>(3, 0));
// 要素に値を代入
grid[0][0] = 1;
grid[0][1] = 2;
grid[0][2] = 3;
grid[1][0] = 4;
grid[1][1] = 5;
grid[1][2] = 6;
grid[2][0] = 7;
grid[2][1] = 8;
grid[2][2] = 9;
return 0;
}
ここに関しては、forループに階層を持たせて、入力することで埋めるのが一般的ですかね。
2.うずまき走査(スパイラル順走査)
int N = grid.size();
vector<int> spiral; // 渦巻き順に取り出した要素を格納
int top = 0, bottom = N - 1;
int left = 0, right = N - 1;
while (top <= bottom && left <= right) {
// 上辺を左から右へ
for (int j = left; j <= right; j++) spiral.push_back(grid[top][j]);
top++;
// 右辺を上から下へ
for (int i = top; i <= bottom; i++) spiral.push_back(grid[i][right]);
right--;
// 下辺を右から左へ
if (top <= bottom) {
for (int j = right; j >= left; j--) spiral.push_back(grid[bottom][j]);
bottom--;
}
// 左辺を下から上へ
if (left <= right) {
for (int i = bottom; i >= top; i--) spiral.push_back(grid[i][left]);
left++;
}
}
このコードでは左上から右にむかって進み、そのまま螺旋状にうずを巻くように進んでいく処理を書いていて、2次元配列をうずまき順で1次元配列に整理しなおしています。
上辺下辺 右辺左辺の壁をどんどん縮小していくイメージです。
3.累積和の作り方
一次元配列に対して「先頭から順に足していった合計」を持つことで、区間の和を高速に求められます。
vector<long long> prefix(spiral.size() + 1, 0);
for (int i = 0; i < spiral.size(); i++) {
prefix[i + 1] = prefix[i] + spiral[i];
}
// 例: 配列の先頭から i 個までの合計は prefix[i]
// 区間 [l, r] の合計は prefix[r+1] - prefix[l] で求められます。
ここではlong long型にすることで余裕を持たせつつ、spiral.size() + 1のサイズをとることで、prefix[0]を0と設定できるようにして累積和を求めやすくしています。
4.まとめ
二次元配列の作り方は vector>
うずまき走査は「境界を縮めながら走査」
累積和は「前計算して区間和をO(1)で求める」
この3つを理解すれば、競プロでよく出る配列・グリッド問題や、さらに DPの基礎 にもつながっていきます。
他にもスマートなやり方があれば是非コメント等で教えてください!!