-
백준(BOJ) 17822번 원판 돌리기알고리즘 풀이/백준(Boj) 2019. 12. 23. 02:06
문제 : 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
풀이 :
문제에 주어진 대로 차근차근 푸는 시뮬레이션 문제였다.
주의할 점은
flag를 통해서 인접한 곳을 발견했는지 여부를 판단했다. 발견하지 못했다면 평균을 구해서
따로 처리해주어야 한다.
copy (cop) 배열을 만들어서 인접한 곳을 발견했을 경우 0으로 만들어 주었다.
이때 0 == 0 일시 flag가 true가 되는 걸 막기 위해 0이 아니라는 조건도 달아주었다.
코드 ( C++ )
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters#include <iostream> #include <vector> using namespace std; int n, m, t; int x, d, k; vector<vector<int>> a; void rotate(vector<int>& v) { int cnt = k; while (cnt--) { int temp = v[m]; for (int i = m; i >= 2; --i) { v[i] = v[i - 1]; } v[1] = temp; } } void reverse(vector<int>& v) { int cnt = k; while (cnt--) { int temp = v[1]; for (int i = 1; i <= m - 1; ++i) { v[i] = v[i + 1]; } v[m] = temp; } } int main() { cin >> n >> m >> t; a = vector < vector<int>>(n + 1, vector<int>(m + 1)); for (int i = 1; i <= n; ++i) for (int j = 1; j <= m; ++j) cin >> a[i][j]; while (t--) { cin >> x >> d >> k; //회전시키기 for (int i = 1; i <= n; ++i) { if (i % x == 0) { if (d == 0) { rotate(a[i]); } else { reverse(a[i]); } } } //인접한 것 지우기 vector<vector<int>> cop(a); bool flag = false; for (int i = 1; i <= n; ++i) { if (a[i][1] != 0 && a[i][1] == a[i][2]) { flag = true; cop[i][1] = 0; cop[i][2] = 0; } if (a[i][1] != 0 && a[i][1] == a[i][m]) { flag = true; cop[i][1] = 0; cop[i][m] = 0; } if (a[i][m] != 0 && a[i][m] == a[i][m - 1]) { flag = true; cop[i][m] = 0; cop[i][m - 1] = 0; } if (a[i][m] != 0 && a[i][m] == a[i][1]) { flag = true; cop[i][m] = 0; cop[i][1] = 0; } } for (int i = 1; i <= n; ++i) for (int j = 2; j <= m - 1; ++j) { if (a[i][j] != 0 && a[i][j] == a[i][j - 1]) { flag = true; cop[i][j] = 0; cop[i][j - 1] = 0; } if (a[i][j] != 0 && a[i][j] == a[i][j + 1]) { flag = true; cop[i][j] = 0; cop[i][j + 1] = 0; } } for (int j = 1; j <= m; ++j) { if (a[1][j] != 0 && a[1][j] == a[2][j]) { flag = true; cop[1][j] = 0; cop[2][j] = 0; } } for (int j = 1; j <= m; ++j) { if (a[n][j] != 0 && a[n][j] == a[n - 1][j]) { flag = true; cop[n][j] = 0; cop[n - 1][j] = 0; } } for (int i = 2; i <= n - 1; ++i) for (int j = 1; j <= m; ++j) { if (a[i][j] != 0 && a[i][j] == a[i - 1][j]) { flag = true; cop[i][j] = 0; cop[i - 1][j] = 0; } if (a[i][j] != 0 && a[i][j] == a[i + 1][j]) { flag = true; cop[i][j] = 0; cop[i + 1][j] = 0; } } a = cop; // 합 구하기 int sum = 0; for (int i = 1; i <= n; ++i) for (int j = 1; j <= m; ++j) sum += a[i][j]; //변한게 없다 if (!flag) { double avg = 0; int cnt = 0; for (int i = 1; i <= n; ++i) for (int j = 1; j <= m; ++j) { if (a[i][j] > 0) cnt++; } avg = (double)sum / (double)cnt; for (int i = 1; i <= n; ++i) for (int j = 1; j <= m; ++j) { if (a[i][j] > 0) { if (a[i][j] > avg) a[i][j] -= 1; else if (a[i][j] < avg) a[i][j] += 1; } } } } int ans = 0; for (int i = 1; i <= n; ++i) for (int j = 1; j <= m; ++j) ans += a[i][j]; cout << ans << "\n"; return 0; } '알고리즘 풀이 > 백준(Boj)' 카테고리의 다른 글
백준(BOJ) 16956번 늑대와 양 (0) 2019.12.29 백준(BOJ) 16959번 체스판 여행 1 (0) 2019.12.26 백준(BOJ) 17143번 낚시왕 (0) 2019.12.19 백준(BOJ) 16918번 봄버맨 (0) 2019.12.19 백준 BOJ 13458번 시험 감독 (0) 2019.12.17