https://www.acmicpc.net/problem/17822
시뮬레이션 + bfs(?) 로 풀리는 간단한(?) 문제.
다음과 같은 방법으로 풀 수 있다.
1. 원판을 돌린다. 이 때 반시계방향으로 k번 돌리는 것은, 시계 방향으로 M-k번 돌리는 것과 같기 때문에
시계 방향으로 돌리는 것만 구현했다. 효율적인 방식은 아니지만 빠르게 구현하기 위해서(^^;)...
2. 각 지점에서 bfs를 돌면서 인접한 수가 같은지 확인한다. 같은 수는 모두 0으로 바꾸어준다.
2-1. 인접한 수가 모두 다르다면 전체 수의 평균을 구한 다음 조건에 따라 1을 더하거나 빼준다.
3. T회 반복한다
전체 코드
더보기
전체 코드
#include <iostream>
#include <queue>
using namespace std;
int N, M, T, x, d, k;
int circles[51][50];
int rd[4] = { 0,0,+1,-1 };
int cd[4] = { +1,-1,0,0 };
void rotate(int x, int d, int k) {
int t = k;
if (d == 1) {
t = M - k;
}
int multiplier = x;
for (int k = 0; k < t; k++) {
for (int i = 1;; i++) {
multiplier = x * i;
if (multiplier > N) break;
int tmp = circles[multiplier][M-1];
for (int j = M-2; j >= 0; j--) {
circles[multiplier][j + 1] = circles[multiplier][j];
}
circles[multiplier][0] = tmp;
}
}
}
bool bfs(int r, int c) {
queue<pair<int,int>> q;
vector<pair<int, int>> list;
bool v[51][51] = { false, };
q.push(make_pair(r, c));
list.push_back(make_pair(r, c));
v[r][c] = true;
int nr, nc, cr, cc;
while (!q.empty()) {
cr = q.front().first;
cc = q.front().second;
q.pop();
for (int i = 0; i < 4; i++) {
nr = cr + rd[i];
nc = cc + cd[i];
if (nc == -1) nc = M-1;
else if (nc == M) nc = 0;
if (nr == 0 || nr == N + 1) continue;
if (v[nr][nc]) continue;
if (circles[nr][nc] != circles[r][c]) continue;
v[nr][nc] = true;
q.push(make_pair(nr, nc));
list.push_back(make_pair(nr, nc));
}
}
if (list.size() == 1) return false;
else {
for (int i = 0; i < list.size(); i++) {
circles[list[i].first][list[i].second] = 0;
}
return true;
}
}
pair<double,double> avg() {
double sum= 0.0, cnt=0.0;
for (int i = 1; i <= N; i++) {
for (int j = 0; j < M; j++) {
if (circles[i][j] == 0) continue;
sum += circles[i][j];
cnt++;
}
}
return make_pair(sum, cnt);
}
void run(int x, int d, int k) {
if(k != 0) rotate(x, d, k);
bool flag = true;
double sum = 0;
double cnt = 0;
for (int i = 1; i <= N; i++) {
for (int j = 0; j < M; j++) {
if (circles[i][j] == 0) continue;
if (bfs(i, j)) flag = false;
}
}
if (flag) {
pair<double, double> p;
p = avg();
sum = p.first;
cnt = p.second;
if (cnt != 0) {
double mean = sum / cnt;
for (int i = 1; i <= N; i++) {
for (int j = 0; j < M; j++) {
if (circles[i][j] == 0) continue;
if (circles[i][j] < mean) circles[i][j] += 1;
else if (circles[i][j] > mean) circles[i][j] -= 1;
}
}
}
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
cin >> N >> M >> T;
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
cin >> circles[i+1][j];
}
}
for (int i = 0; i < T; i++) {
cin >> x >> d >> k;
run(x, d, k);
}
int ans = 0;
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
ans += circles[i + 1][j];
}
}
cout << ans;
}
반성(...)
더보기
bfs로 다음 탐색을 진행할 때 nc를 바꿔주는 조건을
if (cc == 0 && i == 0) nc = M-1;
else if (cc == M-1 && i == 1) nc = 0;
라는 이상한 조건을 걸어주는 바람에 뻘짓을 엄청나게 했다^^;
원래 의도는 nc가 -1 이나 M이 되면 M과 0으로 바꾸어 주려는 것이었는데,
두 줄 모두 원래 의도했던 조건에서 작동하지 않는다
(cd의 인덱스를 착각했었다. 그리고 애초에 nc == -1 이나 nc == M으로 짜면 더 간단했는데 왜 이렇게 했을까? 나도 날 모르겠다ㅠㅠ)
'algorithm' 카테고리의 다른 글
221. Maximal Square (0) | 2021.07.13 |
---|---|
1423. maximum points you can obtain from cards (0) | 2021.07.12 |
[BOJ 15686] 치킨 배달 (0) | 2019.04.13 |
[BOJ 16236] 아기 상어 (0) | 2019.04.09 |
[BOJ14889] 스타트와 링크 (0) | 2019.03.28 |
댓글