홍시홍의 프로그래밍

[백준 17822] 원판 돌리기 본문

알고리즘 문제풀이/백준

[백준 17822] 원판 돌리기

홍시홍 2020. 1. 30. 23:32

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

 

요구사항

1. 회전 판 돌리기

2. 인접한거 확인하기

3. 확인 후 처리하기

 

풀이

1. 초기값을 dq에 넣는다

2. 회전 입력 값에 의해서 회전 판을 돌린다

3. 인접한 게 동일한지 검사한다(예외 처리)

4. 있을 경우 0, 없을 경우 평균 값 기준으로 +-1 처리해주기

5. 정답 구하기

 

평균 값이랑 같으면 아무 행동 하지 않는다.....

문제 잘읽기 ㅠㅠ

 

#include <iostream>
#include <deque>
#include <string>
#include <string.h>
#include <queue>
using namespace std;
deque<int> dq[51];
struct go {
	int x;
	int y;
};
int visit[51][51];
int n, m, t;
int dc[4] = { 0,-1,0,1 };
int dr[4] = { -1,0,1,0 };
void rotate(int x, int d, int k) {
	
	//돌렸다.
	for (int i = 1; x*i <= n; i++) {
		for (int j = 0; j < k; j++) {
			if (d == 0) {
				int temp = dq[x*i-1].back();
				dq[x*i -1].pop_back();
				dq[x*i -1].push_front(temp);

			}
			else if (d == 1) {
				int temp = dq[x*i -1].front();
				dq[x*i -1].pop_front();
				dq[x*i -1].push_back(temp);
			}
		}
	}

	int flag = 0;
	//인접한거 같은지 검사
	memset(visit, 0, sizeof(visit));
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			if (dq[i][j] > 0 && visit[i][j] == 0) {
				int findflag = 0;
				for (int k = 0; k < 4; k++) {
					int nr = i + dr[k];
					int nc = j + dc[k];
					if (j == 0 && k == 1)
						nc = m - 1;
					if (j == m - 1 && k == 3)
						nc = 0;
					if (nr < 0 || nc < 0 || nr >= n || nc >= m) {
						continue;
					}
					if (dq[nr][nc] == dq[i][j]) {
						findflag = 1;
						break;
					}
				}
				if (findflag == 1) {
					flag = 1;
					queue<go> q;
					q.push({ i,j });
					visit[i][j] = 1;
					while (!q.empty()) {
						int r = q.front().x;
						int c = q.front().y;
						q.pop();
						for (int k = 0; k < 4; k++) {
							int nr = r + dr[k];
							int nc = c + dc[k];
							if (c == 0 && k == 1)
								nc = m - 1;
							if (c == m - 1 && k == 3)
								nc = 0;
							if (nr < 0 || nc < 0 || nr >= n || nc >= m)
								continue;
							if (dq[nr][nc] == dq[r][c] && visit[nr][nc] == 0) {
								visit[nr][nc] = 1;
								q.push({ nr,nc });
							}
						}
					}
				}
			}
		}
	}
	double avg = 0;
	if (flag == 0) {
		double cnt = 0;
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < m; j++) {
				if (dq[i][j] > 0) {
					cnt++;
					avg += dq[i][j];
				}
			}
		}
		avg = avg / cnt;
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < m; j++) {
				if (dq[i][j] == 0)
					continue;
				if (dq[i][j] > avg) {
					dq[i][j] -=1;
				}
				else if(dq[i][j]<avg){
					dq[i][j] += 1;
				}
			}
		}

	}
	else {
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < m; j++) {
				if (visit[i][j] == 1) {
					dq[i][j] = 0;
				}
			}
		}
	}



}
int main() {
	cin >> n >> m >> t;
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			int x;
			cin >> x;
			dq[i].push_back(x);
		}
	}

	for (int i = 0; i < t; i++) {
		int x, d, k;
		cin >> x >> d >> k;
		rotate(x, d, k);

	}
	int ans = 0;
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			if (dq[i][j] > 0) {
				ans += dq[i][j];
			}
		}
	}
	cout << ans << endl;

}

 

'알고리즘 문제풀이 > 백준' 카테고리의 다른 글

[백준 13458] 시험감독  (0) 2020.01.31
[백준 3190] 뱀  (0) 2020.01.31
[백준 13460] 구슬 탈출2  (0) 2020.01.29
[백준 3020] 개똥벌레  (0) 2020.01.14
[백준 2959] 거북이  (0) 2020.01.14
Comments