백준 / 배열 돌리기 3 - 상하반전, 회전, 그룹 회전 / C++

2026. 2. 11. 22:26·coding test - C++/백준
728x90
반응형

 

*문제 출처는 백준에 있습니다.

문제 제목: 배열 돌리기 3

문제 사이트: https://www.acmicpc.net/problem/16935

 

배열 돌리기 3

시간 제한메모리 제한제출정답맞힌 사람정답 비율
2 초 512 MB 13616 7055 5185 50.873%

문제

크기가 N×M인 배열이 있을 때, 배열에 연산을 R번 적용하려고 한다. 연산은 총 6가지가 있다.

1번 연산은 배열을 상하 반전시키는 연산이다.

1 6 2 9 8 4 → 4 2 9 3 1 8
7 2 6 9 8 2 → 9 2 3 6 1 5
1 8 3 4 2 9 → 7 4 6 2 3 1
7 4 6 2 3 1 → 1 8 3 4 2 9
9 2 3 6 1 5 → 7 2 6 9 8 2
4 2 9 3 1 8 → 1 6 2 9 8 4
   <배열>       <연산 결과>

2번 연산은 배열을 좌우 반전시키는 연산이다.

1 6 2 9 8 4 → 4 8 9 2 6 1
7 2 6 9 8 2 → 2 8 9 6 2 7
1 8 3 4 2 9 → 9 2 4 3 8 1
7 4 6 2 3 1 → 1 3 2 6 4 7
9 2 3 6 1 5 → 5 1 6 3 2 9
4 2 9 3 1 8 → 8 1 3 9 2 4
   <배열>       <연산 결과>

3번 연산은 오른쪽으로 90도 회전시키는 연산이다.

1 6 2 9 8 4 → 4 9 7 1 7 1
7 2 6 9 8 2 → 2 2 4 8 2 6
1 8 3 4 2 9 → 9 3 6 3 6 2
7 4 6 2 3 1 → 3 6 2 4 9 9
9 2 3 6 1 5 → 1 1 3 2 8 8
4 2 9 3 1 8 → 8 5 1 9 2 4
   <배열>       <연산 결과>

4번 연산은 왼쪽으로 90도 회전시키는 연산이다.

1 6 2 9 8 4 → 4 2 9 1 5 8
7 2 6 9 8 2 → 8 8 2 3 1 1
1 8 3 4 2 9 → 9 9 4 2 6 3
7 4 6 2 3 1 → 2 6 3 6 3 9
9 2 3 6 1 5 → 6 2 8 4 2 2
4 2 9 3 1 8 → 1 7 1 7 9 4
   <배열>       <연산 결과>

5, 6번 연산을 수행하려면 배열을 크기가 N/2×M/2인 4개의 부분 배열로 나눠야 한다. 아래 그림은 크기가 6×8인 배열을 4개의 그룹으로 나눈 것이고, 1부터 4까지의 수로 나타냈다.

1 1 1 1 2 2 2 2
1 1 1 1 2 2 2 2
1 1 1 1 2 2 2 2
4 4 4 4 3 3 3 3
4 4 4 4 3 3 3 3
4 4 4 4 3 3 3 3

5번 연산은 1번 그룹의 부분 배열을 2번 그룹 위치로, 2번을 3번으로, 3번을 4번으로, 4번을 1번으로 이동시키는 연산이다.

3 2 6 3 1 2 9 7 → 2 1 3 8 3 2 6 3
9 7 8 2 1 4 5 3 → 1 3 2 8 9 7 8 2
5 9 2 1 9 6 1 8 → 4 5 1 9 5 9 2 1
2 1 3 8 6 3 9 2 → 6 3 9 2 1 2 9 7
1 3 2 8 7 9 2 1 → 7 9 2 1 1 4 5 3
4 5 1 9 8 2 1 3 → 8 2 1 3 9 6 1 8
     <배열>            <연산 결과>

6번 연산은 1번 그룹의 부분 배열을 4번 그룹 위치로, 4번을 3번으로, 3번을 2번으로, 2번을 1번으로 이동시키는 연산이다.

3 2 6 3 1 2 9 7 → 1 2 9 7 6 3 9 2
9 7 8 2 1 4 5 3 → 1 4 5 3 7 9 2 1
5 9 2 1 9 6 1 8 → 9 6 1 8 8 2 1 3
2 1 3 8 6 3 9 2 → 3 2 6 3 2 1 3 8
1 3 2 8 7 9 2 1 → 9 7 8 2 1 3 2 8
4 5 1 9 8 2 1 3 → 5 9 2 1 4 5 1 9
     <배열>            <연산 결과>

입력

첫째 줄에 배열의 크기 N, M과 수행해야 하는 연산의 수 R이 주어진다.

둘째 줄부터 N개의 줄에 배열 A의 원소 Aij가 주어진다.

마지막 줄에는 수행해야 하는 연산이 주어진다. 연산은 공백으로 구분되어져 있고, 문제에서 설명한 연산 번호이며, 순서대로 적용시켜야 한다.

출력

입력으로 주어진 배열에 R개의 연산을 순서대로 수행한 결과를 출력한다.

제한

  • 2 ≤ N, M ≤ 100
  • 1 ≤ R ≤ 1,000
  • N, M은 짝수
  • 1 ≤ Aij ≤ 108

나의 풀이

#include <stdio.h>

#define MAX (100+10)

#define FLIP_UPDOWN (1) // 가운데를 기준으로 상하 반전
#define FLIP_LEFTRIFHT (2) // 가운데를 기준으로 좌우 반전
#define ROTATE_RIGHT (3) // 오른쪽으로 90도 회전
#define ROTATE_LEFT (4) // 왼쪽으로 90도 회전
#define SPLIT_ROTATE_RIGHT (5) // 네가지 그룹으로 나눈 뒤 오른쪽으로 회전
#define SPLIT_ROTATE_LEFT (6) // 네가지 그룹으로 나눈 뒤 왼쪽으로 회전

int N, M, R, Command;
int MAP[MAX][MAX];
int temp[MAX][MAX];


void input() {

	scanf("%d %d %d", &N, &M, &R);
	for (int r = 0; r < N; r++) {
		for (int c = 0; c < M; c++) {
			scanf("%d", &MAP[r][c]);
		}
	}
}

void printMAP(int originMAP[MAX][MAX]){

	for (int r = 0; r < N; r++) {
		for (int c = 0; c < M; c++) {
			printf("%d ", originMAP[r][c]);
		}
		putchar('\n');
	}
}

void copyMAP(int originMAP[MAX][MAX], int copiedMAP[MAX][MAX]) {

	for (int r = 0; r < N; r++) {
		for (int c = 0; c < M; c++) {
			temp[r][c] = originMAP[r][c];
		}
	}
}

// function

void flipUpdown() {
	copyMAP(MAP, temp);

	for (int r = 0; r < N; r++) {
		for (int c = 0; c < M; c++) {
			MAP[r][c] = temp[N - r - 1][c];
		}
	}
}

void flipLeftRight() {
	copyMAP(MAP, temp);
	for (int r = 0; r < N; r++) {
		for (int c = 0; c < M; c++) {
			MAP[r][c] = temp[r][M - c - 1];
		}
	}
}

void rotate_right() {
	copyMAP(MAP, temp);

	int t;
	t = M;
	M = N;
	N = t;

	for (int r = 0; r < N; r++) {
		for (int c = 0; c < M; c++) {
			MAP[r][c] = temp[M-1-c][r];
		}
	}
}


void rotate_left() {
	copyMAP(MAP, temp);
	int t;
	t = M;
	M = N;
	N = t;

	for (int r = 0; r < N; r++) {
		for (int c = 0; c < M; c++) {
			MAP[r][c] = temp[c][N-r-1];
		}
	}

}

void split_rotate_right() {
	copyMAP(MAP, temp);
	int sr1, sr2, sr3, sr4;
	int sc1, sc2, sc3, sc4;
	int halfN, halfM;

	halfN = (N / 2);
	halfM = (M / 2);

	sr1 = sc1 = 0;
	sr2 = 0, sc2 = halfM;
	sr3 = halfN, sc3 = halfM;
	sr4 = halfN, sc4 = 0;

	for (int r = 0; r < halfN; r++) {
		for (int c = 0; c < halfM; c++) {
			MAP[sr2 + r][sc2 + c] = temp[sr1 + r][sc1 + c];
		}
	}

	for (int r = 0; r < halfN; r++) {
		for (int c = 0; c < halfM; c++) {
			MAP[sr3 + r][sc3 + c] = temp[sr2 + r][sc2 + c];
		}
	}

	for (int r = 0; r < halfN; r++) {
		for (int c = 0; c < halfM; c++) {
			MAP[sr4 + r][sc4 + c] = temp[sr3 + r][sc3 + c];
		}
	}
	for (int r = 0; r < halfN; r++) {
		for (int c = 0; c < halfM; c++) {
			MAP[sr1 + r][sc1 + c] = temp[sr4 + r][sc4 + c];
		}
	}
}

void split_rotate_left() {
	copyMAP(MAP, temp);
	int sr1, sr2, sr3, sr4;
	int sc1, sc2, sc3, sc4;
	int halfN, halfM;

	halfN = (N / 2);
	halfM = (M / 2);

	sr1 = sc1 = 0;
	sr2 = 0, sc2 = halfM;
	sr3 = halfN, sc3 = halfM;
	sr4 = halfN, sc4 = 0;

	for (int r = 0; r < halfN; r++) {
		for (int c = 0; c < halfM; c++) {
			MAP[sr4 + r][sc4 + c] = temp[sr1 + r][sc1 + c];
		}
	}

	for (int r = 0; r < halfN; r++) {
		for (int c = 0; c < halfM; c++) {
			MAP[sr3 + r][sc3 + c] = temp[sr4 + r][sc4 + c];
		}
	}

	for (int r = 0; r < halfN; r++) {
		for (int c = 0; c < halfM; c++) {
			MAP[sr2 + r][sc2 + c] = temp[sr3 + r][sc3 + c];
		}
	}
	for (int r = 0; r < halfN; r++) {
		for (int c = 0; c < halfM; c++) {
			MAP[sr1 + r][sc1 + c] = temp[sr2 + r][sc2 + c];
		}
	}
}

// main
int main() {

	input();
	for (int i = 0; i < R; i++) {
		scanf("%d", &Command);
		if (Command == FLIP_UPDOWN) flipUpdown();
		else if (Command == FLIP_LEFTRIFHT) flipLeftRight();
		else if (Command == ROTATE_RIGHT) rotate_right();
		else if (Command == ROTATE_LEFT) rotate_left();
		else if (Command == SPLIT_ROTATE_RIGHT) split_rotate_right();
		else if (Command == SPLIT_ROTATE_LEFT) split_rotate_left();
		
	}
	printMAP(MAP);
	return 0;
}

 

 


※ 알아야 할 것

- 1,2,3,4 ... 같이 되어있는거는 그냥 매크로 함수로 보기 좋게 정리하자!

- 생각보다 회ㅓㄴ은 어렵지 않다...  평소에는 그림 그리면서 좌표 대입해보면서 감을 익혀나가는게 중요할 

- 직사각형 회전은 N, M 바뀌는거 유의하기!!

 

728x90
반응형

'coding test - C++ > 백준' 카테고리의 다른 글

백준 / 달팽이 / C++  (0) 2026.02.12
백준 / 배열 돌리기 6 - 부분 배열 반전, 회전 / C++  (0) 2026.02.12
백준 / 배열 돌리기 2 / C++  (0) 2026.02.11
백준 / 배열 돌리기 1 / C++  (0) 2026.02.11
백준 / 배열 돌리기 / C++  (0) 2026.02.10
'coding test - C++/백준' 카테고리의 다른 글
  • 백준 / 달팽이 / C++
  • 백준 / 배열 돌리기 6 - 부분 배열 반전, 회전 / C++
  • 백준 / 배열 돌리기 2 / C++
  • 백준 / 배열 돌리기 1 / C++
sillon
sillon
꾸준해지려고 합니다..
    반응형
  • sillon
    sillon coding
    sillon
  • 전체
    오늘
    어제
    • menu (639)
      • notice (2)
      • python (68)
        • 자료구조 & 알고리즘 (23)
        • 라이브러리 (19)
        • 기초 (8)
        • 자동화 (14)
        • 보안 (1)
      • coding test - python (304)
        • Programmers (169)
        • 백준 (76)
        • Code Tree (22)
        • 기본기 문제 (37)
      • coding test - C++ (3)
        • Programmers (11)
        • 백준 (8)
        • 기본기문제 (3)
      • 공부정리 (139)
        • 신호처리 시스템 (0)
        • Deep learnig & Machine lear.. (41)
        • Data Science (18)
        • Computer Vision (17)
        • NLP (40)
        • Dacon (2)
        • 모두를 위한 딥러닝 (강의 정리) (4)
        • 모두의 딥러닝 (교재 정리) (9)
        • 통계 (3)
      • HCI (23)
        • Haptics (7)
        • Graphics (11)
        • Arduino (4)
      • Project (21)
        • Web Project (1)
        • App Project (1)
        • Paper Project (1)
        • 캡스톤디자인2 (17)
        • etc (1)
      • OS (10)
        • Ubuntu (9)
        • Rasberry pi (1)
      • App & Web (9)
        • Android (7)
        • javascript (2)
      • C++ (5)
        • 기초 (5)
      • Cloud & SERVER (8)
        • Git (2)
        • Docker (1)
        • DB (4)
      • Paper (7)
        • NLP Paper review (6)
      • 데이터 분석 (1)
        • GIS (0)
      • daily (2)
        • 대학원 준비 (0)
      • 영어공부 (6)
        • job interview (2)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    Python
    백준
    소수
    programmers
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
sillon
백준 / 배열 돌리기 3 - 상하반전, 회전, 그룹 회전 / C++
상단으로

티스토리툴바