Official
D - 画像回転エディタ / Image Rotation Editor Editorial
by
D - 画像回転エディタ / Image Rotation Editor Editorial
by
kyopro_friends
以下、index は 0 からとします。
まず「\(K\times K\) のグリッド全体を右に \(90\) 度回す」という操作を考えます。 このとき、\((i,j)\) のマスは \((j,K-1-i)\) に移ります。よって
for i in 0..K-1:
for j in 0..K-1:
T[j][K-1-i]=S[i][j]
のような方法により、\(S\) を右に \(90\) 度回したグリッド \(T\) を得ることができます。
元の問題もほとんど同様に、\((r,c)\) を左上とする \(K\times K\) の範囲を右に \(90\) 度回したグリッドは
for i in 0..K-1:
for j in 0..K-1:
T[j][K-1-i]=S[r+i][c+j]
のように得ることができます。こうして得られたグリッドで元のグリッドを上書きすることで、所望の操作を実現できます。
クエリ \(1\) 回あたりの計算量は \(O(K^2)\) なので全体の計算量は \(O(QK^2)\) となります。\(QK^2 \leq 2\times 10^7\) の制約より、この解法は十分高速です。
実装例 (C++)
#include<bits/stdc++.h>
using namespace std;
int main(){
int n, k, q;
cin >> n >> k >> q;
vector<string> s(n);
for(int i=0; i<n; i++) cin >> s[i];
vector<string> t(k, string(k, '0'));
for(int i=0; i<q; i++){
int r, c;
cin >> r >> c;
r--, c--;
for(int i=0; i<k; i++){
for(int j=0; j<k; j++){
t[j][k-1-i] = s[r+i][c+j];
}
}
for(int i=0; i<k; i++){
for(int j=0; j<k; j++){
s[r+i][c+j] = t[i][j];
}
}
}
for(int i=0; i<n; i++) cout << s[i] << endl;
}
実装例 (Python)
N, K, Q = map(int, input().split())
S = [list(input()) for _ in range(N)]
T = [['0']*K for _ in range(K)]
for _ in range(Q):
r, c = map(int, input().split())
r -= 1
c -= 1
for i in range(K):
for j in range(K):
T[j][K-1-i] = S[r+i][c+j]
for i in range(K):
for j in range(K):
S[r+i][c+j] = T[i][j]
for s in S:
print("".join(s))
posted:
last update:
