-
백준 17822번 원판돌리기PS 2020. 2. 4. 21:55
https://www.acmicpc.net/problem/17822
17822번: 원판 돌리기
반지름이 1, 2, ..., N인 원판이 크기가 작아지는 순으로 바닥에 놓여있고, 원판의 중심은 모두 같다. 원판의 반지름이 i이면, 그 원판을 i번째 원판이라고 한다. 각각의 원판에는 M개의 정수가 적혀있고, i번째 원판에 적힌 j번째 수의 위치는 (i, j)로 표현한다. 수의 위치는 다음을 만족한다. (i, 1)은 (i, 2), (i, M)과 인접하다. (i, M)은 (i, M-1), (i, 1)과 인접하다. (i, j)는 (i, j-1), (i, j
www.acmicpc.net
<접근방법>
시뮬레이션 문제입니다.
인접규칙이 언뜻 보기에는 까다로웠고
문제 동작도 예제를 통해 확인을 해봐야만 정확한 부분이 있었습니다.
인접조건은 상식적으로 인접한 것끼리 인접한다는 것이고
구현은 2중 for문으로 할 수 있었습니다.
회전은 배열 인덱스 조작으로 하려고 했으나, 제 머리 RPM이 더 이상 안올라가서 덱으로 하였습니다...ㅠ
<코드>
#include <iostream> #include <algorithm> #include <deque> #include <vector> using namespace std; struct point { int y, x; }; int n, m, t; int x, d, k; int map[51][51]; int cal_sum() { int sum = 0; for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { sum += map[i][j]; } } return sum; } void make_rotate(int num, deque <int> &deq) { for (int j = 0; j < m; j++) { map[num][j] = deq[j]; } } //시계방향 회전 void rotate_c(int num, deque <int> &deq) { for (int i = 0; i < k; i++) { int tmp = deq.back(); deq.pop_back(); deq.push_front(tmp); } } //반시계방향 회전 void rotate_rc(int num, deque <int> &deq) { for (int i = 0; i < k; i++) { int tmp = deq.front(); deq.pop_front(); deq.push_back(tmp); } } //돌리고 난 후의 작업 void rewrite(vector<point> v) { int sz = v.size(); if (sz != 0) { for (int i = 0; i < sz; i++) { int y = v[i].y; int x = v[i].x; map[y][x] = 0; } } else { int sum = 0; int cnt = 0; double avg; for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { if (map[i][j] != 0) { cnt++; sum += map[i][j]; } } } avg = (double)sum / cnt; for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { if (map[i][j] == 0) continue; if (map[i][j] > avg) { map[i][j]--; } else if (map[i][j] < avg) { map[i][j]++; } } } } } //인접 확인 void check_near() { vector<point> v; for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { if (map[i][j] == 0) continue; //양 옆 확인 //왼쪽 if (j-1 > 0 && map[i][j] == map[i][j-1]) { v.push_back({i, j}); v.push_back({ i, j-1 }); } //오른쪽 if (j+1 < m && map[i][j] == map[i][j+1]) { v.push_back({ i, j }); v.push_back({ i, j + 1 }); } //상하 확인 //상 if (i-1 > 0 && map[i][j] == map[i-1][j]) { v.push_back({ i, j }); v.push_back({ i-1, j}); } //하 if (i+1 < m && map[i][j] == map[i+1][j]) { v.push_back({ i, j }); v.push_back({ i+1, j}); } //양 끝 if (j == 0 && map[i][0] != 0 && map[i][0] == map[i][m-1]) { v.push_back({ i, 0 }); v.push_back({ i, m-1 }); } } } rewrite(v); } void simul() { for (int i = 1; i <= 25; i++) { int num = x * i; if (num-1 >= n) break;// num-1은 배열을 0부터 썼기 때문에 배수처리를 위함 deque<int> deq; for (int j = 0; j < m; j++) { deq.push_back(map[num-1][j]); } if (d == 0) { rotate_c(num - 1, deq); } else { rotate_rc(num - 1, deq); } make_rotate(num - 1, deq); } check_near(); } int main() { cin >> n >> m >> t; for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { cin >> map[i][j]; } } while (t--) { cin >> x >> d >> k; simul(); } cout << cal_sum() << '\n'; return 0; }
<느낀 점>
-어려운 모듈은 손으로 한번 해보고 코딩하자!
-구현 편의성 또한 중요하다
-문제이해에 예제를 적극 활용하자
반응형'PS' 카테고리의 다른 글
백준 12100번 2048(Easy) (0) 2020.02.06 백준 13460번 구슬 탈출2 (0) 2020.02.04 백준 17837번 새로운 게임2 (0) 2020.01.30 백준 17780번 새로운 게임 (0) 2020.01.29 백준 15898번 피아의 아틀리에 ~신비한 대회의 연금술사~ (0) 2020.01.28