...
행렬의 세로 길이(행 개수) rows, 가로 길이(열 개수) columns, 그리고 회전들의 목록 queries가 주어질 때, 각 회전들을 배열에 적용한 뒤, 그 회전에 의해 위치가 바뀐 숫자들 중 가장 작은 숫자들을 순서대로 배열에 담아 return 하도록 solution 함수를 완성해주세요.
제한사항
- rows는 2 이상 100 이하인 자연수입니다.
- columns는 2 이상 100 이하인 자연수입니다.
- 처음에 행렬에는 가로 방향으로 숫자가 1부터 하나씩 증가하면서 적혀있습니다.
- 즉, 아무 회전도 하지 않았을 때, i 행 j 열에 있는 숫자는 ((i-1) x columns + j)입니다.
- queries의 행의 개수(회전의 개수)는 1 이상 10,000 이하입니다.
- queries의 각 행은 4개의 정수 [x1, y1, x2, y2]입니다.
- x1 행 y1 열부터 x2 행 y2 열까지 영역의 테두리를 시계방향으로 회전한다는 뜻입니다.
- 1 ≤ x1 < x2 ≤ rows, 1 ≤ y1 < y2 ≤ columns입니다.
- 모든 회전은 순서대로 이루어집니다.
- 예를 들어, 두 번째 회전에 대한 답은 첫 번째 회전을 실행한 다음, 그 상태에서 두 번째 회전을 실행했을 때 이동한 숫자 중 최솟값을 구하면 됩니다.
이 문제는 구현 문제이다. 값이 변경되는 규칙을 찾아 코드를 작성했다.
나는 처음에 int minN=1000;으로 해서 실패했다. 문제를 읽어보면 minN의 최대값은 100*100이므로 이 이상의 값을 주어야 한다.
변경해야 할 부분을 4 개로 나누어 새로운 값을 임시 행렬(arr2)에 저장하고 바뀐 값이 최솟값인지 확인한다. 아래 노란 박스처럼 4개의 구역으로 나눈다. 아래 4개의 조건에 해당하는 인덱스 위치 값을 변경한다.
#include <bits/stdc++.h>
using namespace std;
int arr[105][105];
int r, c;
int rotate(int sRow, int sCol, int eRow, int eCol){
int arr2[r][c];
int minN=100000;
for(int i=sRow; i<=eRow; i++){
for(int j=sCol; j<=eCol; j++){
if(i!=sRow && i!=eRow && j!=sCol && j!=eCol) {
arr2[i][j]=arr[i][j];
continue;
}
if(i==sRow && j!=sCol) arr2[i][j] = arr[i][j-1];
if(i!=sRow && j==eCol) arr2[i][j] = arr[i-1][j];
if(i==eRow && j!=eCol) arr2[i][j] = arr[i][j+1];
if(i!=eRow && j==sCol) arr2[i][j] = arr[i+1][j];
minN = min(minN, arr2[i][j]);
}
}
for(int i=sRow; i<=eRow; i++)
for(int j=sCol; j<=eCol; j++)
arr[i][j] = arr2[i][j];
return minN;
}
vector<int> solution(int rows, int columns, vector<vector<int>> queries) {
r = rows;
c = columns;
int count=1;
for(int i=0; i<rows; i++)
for(int j=0; j<columns; j++)
arr[i][j]=count++;
vector<int> answer;
for(auto query: queries){
int n = rotate(query[0]-1,query[1]-1,query[2]-1,query[3]-1);
answer.push_back(n);
// for(int i=0; i<rows; i++){
// for(int j=0; j<columns; j++)
// cout<<arr[i][j]<<" ";
// cout<<'\n';
// }
}
return answer;
}