문제 링크
주의사항
- JAVA를 사용하여 프로그램을 사용하였습니다.
- 백준에서 코드를 작성하였을 때 아래 형태에서 Main에서 결과가 출력되어야 합니다.
public class Main{
public static void main(String[] args){
}
}
문제 설명
접근 방법
이 문제에 핵심은
1. 주어진 배열을 문제에서 설명하는 6가지 방법으로 변경할 수 있도록 합니다.
2. R개의 변경이 끝난 뒤 배열을 결과로 출력합니다.
사용되는 배열
arr[][] : 입력 배열을 저장하고 변경되어 결과로 출력되는 배열
각 변경되는 명령어에 규칙을 찾아보면
1번 연산.
간단한 상하반전으로 배열의 값들을 변경해주면 됩니다.
2번 연산
간단한 좌우반전으로 배열의 값들을 변경해주면 됩니다.
3번 연산
오른쪽 90도 회전
회전 전
1(0,0) | 2(0,1) |
3(1,0) | 4(1,1) |
5(2,0) | 6(2,1) |
회전 후
5(0,0) | 3(0,1) | 1(0,2) |
6(1,0) | 4(1,1) | 2(1,2) |
1 : (0, 0) -> (0, 2)2 : (0, 1) -> (1, 2)3 : (1, 0) -> (0, 1)4 : (1, 1) -> (1, 1)5 : (2, 0) -> (0, 0)6 : (2, 1) -> (1, 0)
규칙은
(i, j) -> (j, 열 최대값 - i)
4번연산
왼쪽 90도 회전
회전 전
1(0,0) | 2(0,1) |
3(1,0) | 4(1,1) |
5(2,0) | 6(2,1) |
회전 후
2(0,0) | 4(0,1) | 6(0,2) |
1(1,0) | 3(1,1) | 5(1,2) |
1 : (0, 0) -> (1, 0)
2 : (0, 1) -> (0, 0)
3 : (1, 0) -> (1, 1)
4 : (1, 1) -> (0, 1)
5 : (2, 0) -> (1, 2)
6 : (2, 1) -> (0, 2)
규칙은
(i, j) -> (행 최대값-j, i)
5~6번에서는 배열을 4분면으로 나누어 값을 변경하는 것으로 아래와 같이 표현할 수 있습니다.
1(0,0) | 1 | 2(0,2) | 2 |
1 | 1 | 2 | 2 |
4(2,0) | 4 | 3(2,2) | 3 |
4 | 4 | 3 | 3 |
1사분면 시작값은 (0, 0)
2사분면 시작값은 (0, M/2)
3사분면 시작값은 (N/2, M/2)
4사분면 시작값은 (N/2, 0)
표현할 수 있습니다.
5번 연산
1사분면 -> 2사분면
2사분면 -> 3사분면
3사분면 -> 4사분면
4사분면 -> 1사분면
각 사분면 시작값을 기준으로 값을 변경해주면 됩니다.
만약 1사분면 -> 2사분면일 때
(0, 0) -> (0, N/2)처럼 옮기시면 됩니다.
6번 연산
1사분면 -> 4사분면
4사분면 -> 3사분면
3사분면 -> 2사분면
2사분면 -> 1사분면
각 사분면 시작값을 기준으로 값을 변경해주면 됩니다.
만약 1사분면 -> 4사분면
(0, 0) -> (N/2, 0)
문제를 해결한 알고리즘의 과정입니다.
1. 입력값 N×M 배열의 값과 R개의 연산을 받았습니다.
2. 각 연산의 규칙에 맞게 배열을 변경해줍니다.
3. 연산이 끝난 뒤 배열의 값들을 결과로 출력합니다.
- BufferedReader를 사용하여 입력 값을 받았습니다.
- StringTokenizer를 이용하여 N×M배열과 R개의 연산을 나누었습니다.
- 각 연산에 맞게 upsideDown/reverseLeftAndRight/rightRotations/leftRotations/subarray_five/subarray_six 함수를 수행하였습니다.
- 연산에 변경을 수행하는 change/subarrayChange/leftRotationsChange/rightRotationsChange 함수를 수행하였습니다.
- BufferedWriter에 연산으로 변경된 최종 배열을 저장하였습니다.
- BufferedWriter에 저장된 값을 결과로 출력하였습니다.
- change함수는 3,4번 연산에 N과 M을 바꾸는 기능을 수행하였습니다.
- subarrayChange함수는 5,6번 연산에 사분면을 바꾸는 기능을 수행하였습니다.
- leftRotationsChange함수는 4번 연산에 값을 왼쪽 90도로 이동하는 기능을 수행하였습니다.
- rightRotationsChange함수는 4번 연산에 값을 왼쪽 90도로 이동하는 기능을 수행하였습니다.
결과 코드
import java.io.*;
import java.util.*;
public class Main{
static int[][] arr; //입력되는 배열 저장
static int N,M,R;
public static void main(String[] arg) throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
//입력값 처리하는 BufferedReader
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
//결과값 출력하는 BufferedWriter
//---------입력값 저장 및 배열 초기화-------
StringTokenizer st = new StringTokenizer(br.readLine()," ");
N = Integer.parseInt(st.nextToken());
M = Integer.parseInt(st.nextToken());
R = Integer.parseInt(st.nextToken());
arr = new int[N][M];
for(int i=0;i<N;i++) {
st = new StringTokenizer(br.readLine()," ");
for(int j=0;j<M;j++) {
arr[i][j] = Integer.parseInt(st.nextToken());
}
}
st = new StringTokenizer(br.readLine()," ");
for(int i=0;i<R;i++) {
String command = st.nextToken();
if(command.equals("1")) //연산1.
upsideDown();
else if(command.equals("2")) //연산2.
reverseLeftAndRight();
else if(command.equals("3")) //연산3.
rightRotations();
else if(command.equals("4")) //연산4.
leftRotations();
else if(command.equals("5")) //연산5
subarray_five();
else //연산 6
subarray_six();
}
//배열 결과 BufferedWriter 저장
for(int i=0;i<N;i++) {
for(int j=0;j<M;j++) {
bw.write(arr[i][j] + " ");
}
bw.newLine();
}
bw.flush(); //결과 출력
bw.close();
br.close();
}
//1번 연산 상하반전 수행
static void upsideDown() {
for(int i=0;i<N/2;i++) {
for(int j=0;j<M;j++) {
int temp = arr[N-1-i][j];
arr[N-1-i][j] = arr[i][j];
arr[i][j] = temp;
}
}
return;
}
//2번 연산 좌우 반전 수행
static void reverseLeftAndRight() {
for(int i=0;i<M/2;i++) {
for(int j=0;j<N;j++) {
int temp = arr[j][M-1-i];
arr[j][M-1-i] = arr[j][i];
arr[j][i] = temp;
}
}
return;
}
//3번 연산 오른쪽 90도 이동
static void rightRotations() {
change();
int[][] result = new int[N][M];;
rightRotationsChange(result, N, M);
arr = new int[N][M];
arr = result;
return;
}
//4번 연산 왼쪽 90도 이동
static void leftRotations() {
change();
int[][] result = new int[N][M];
leftRotationsChange(result, N, M);
arr = new int[N][M];
arr = result;
return;
}
//3번 연산에 값 변경하는 함수
static void rightRotationsChange(int[][] temp, int row, int col) {
for(int i=0;i<col;i++) {
for(int j=0;j<row;j++) {
temp[j][col-1-i] = arr[i][j];
}
}
return;
}
//4번 연산에 값 변경하는 함수
static void leftRotationsChange(int[][] temp, int row, int col) {
for(int i=0;i<col;i++) {
for(int j=0;j<row;j++) {
temp[row-1-j][i] = arr[i][j];
}
}
return;
}
//5번 연산 사분면 이동 수행
static void subarray_five() {
int[][] result = new int[N][M];
subarrayChange(result, 0, 0, 0, M/2);
subarrayChange(result, 0, M/2, N/2, M/2);
subarrayChange(result, N/2, M/2, N/2, 0);
subarrayChange(result, N/2, 0, 0, 0);
arr = result;
return;
}
//6번 연산 사분면 이동 수행
static void subarray_six() {
int[][] result = new int[N][M];
subarrayChange(result, 0, 0, N/2, 0);
subarrayChange(result, N/2, 0, N/2, M/2);
subarrayChange(result, N/2, M/2, 0, M/2);
subarrayChange(result, 0, M/2, 0, 0);
arr = result;
return;
}
//5,6번 사분면 배열 변경하는 함수
static void subarrayChange(int[][] temp, int x1, int y1, int x2, int y2) {
for(int i=0;i<N/2;i++) {
for(int j=0;j<M/2;j++) {
temp[x2+i][y2+j] = arr[x1+i][y1+j];
}
}
return;
}
//N,M을 변경하는 함수
static void change() {
int temp = N;
N = M;
M = temp;
return;
}
}
'백준' 카테고리의 다른 글
[백준] code.plus(시뮬레이션과 구현,JAVA)16926번, 배열 돌리기 1 (0) | 2022.05.05 |
---|---|
[백준] 단계별로 풀어보기(단계:27, 동적 계획법과 최단거리 역추적,JAVA)9019번, DSLR (0) | 2022.05.03 |
[백준] 단계별로 풀어보기(단계:27, 동적 계획법과 최단거리 역추적,JAVA)2618번, 경찰차 (0) | 2022.05.01 |
[백준] code.plus(BFS,JAVA)1261번, 알고스팟 (0) | 2022.04.30 |
[백준] 단계별로 풀어보기(단계:16, 누적합,JAVA)11660번, 구간 합 구하기 (0) | 2022.04.29 |
댓글