본문 바로가기
백준 알고리즘/DFS

원판 돌리기

by paysmile 2021. 4. 20.

https://www.acmicpc.net/problem/17822

 

17822번: 원판 돌리기

반지름이 1, 2, ..., N인 원판이 크기가 작아지는 순으로 바닥에 놓여있고, 원판의 중심은 모두 같다. 원판의 반지름이 i이면, 그 원판을 i번째 원판이라고 한다. 각각의 원판에는 M개의 정수가 적혀

www.acmicpc.net

 

#include <iostream>
#include <cstring>

using namespace std;

const int MAX = 51;
int n, m, t;
int x, d, k;
int circle[MAX][MAX];
int temp[MAX][MAX];
int visited[MAX][MAX];
struct MOVE { int x,y; };
MOVE mv[4] = { {-1,0}, {1,0}, {0,1}, {0,-1} };

void CopyCircle() {
	for (int i = 1; i <= n; i++) {
		for (int j = 0; j < m; j++) {
			temp[i][j] = circle[i][j];
		}
	}
}

void MoveCircle() {
	CopyCircle();

	for (int i = 1; i*x <= n; i++) {
		int num = i*x;

		//시계방향 회전
		if (d == 0) {
			int index;
			for (int j = 0; j < m; j++) {
				index = j + k;
				if (index >= m)	index -= m;
				circle[num][index] = temp[num][j];
			}
		}
		//반시계방향 회전
		else {
			int index;
			for (int j = 0; j < m; j++) {
				index = j - k;
				if (index < 0) index += m;
				circle[num][index] = temp[num][j];
			}
		}
	}
}

void dfs(int x, int y, int value) {
	visited[x][y] = 1;

	for (int k = 0; k < 4; k++) {
		int movei = x + mv[k].x;
		int movej = y + mv[k].y;

		if (movej == -1)	movej = m - 1;
		else if (movej == m)	movej = 0;

		if (circle[movei][movej] == value && visited[movei][movej] == -1) {
			circle[x][y] = 0;
			circle[movei][movej] = 0;
			dfs(movei, movej, value);
		}
	}
	return;
}

bool MoveNum() {
	memset(visited, -1, sizeof(visited));
	bool flag = false;

	for (int i = 1; i <= n; i++) {
		for (int j = 0; j < m; j++) {
			if (circle[i][j] != 0 && visited[i][j] == -1) {
				dfs(i, j,circle[i][j]);
				if (circle[i][j] == 0)	flag = true;
			}
		}
	}

	return flag;
}

void CalAverage() {
	double avg = 0;
	int count = 0;

	for (int i = 1; i <= n; i++) {
		for (int j = 0; j < m; j++) {
			if (circle[i][j] != 0) {
				avg += circle[i][j];
				count += 1;
			}
		}
	}

	avg = avg/count;

	for (int i = 1; i <= n; i++) {
		for (int j = 0; j < m; j++) {
			if (circle[i][j] != 0) {
				if (circle[i][j] < avg)	circle[i][j] += 1;
				else if (circle[i][j] > avg)	circle[i][j] -= 1;
			}
		}
	}
	return;
}

int CalSum() {
	int answer = 0;

	for (int i = 1; i <= n; i++) {
		for (int j = 0; j < m; j++) {
			if(circle[i][j] != 0)
				answer += circle[i][j];
		}
	}
	return answer;
}

int main(void) {
	cin >> n >> m >> t;

	for (int i = 1; i <= n; i++) {
		for (int j = 0; j < m; j++) {
			cin >> circle[i][j];
		}
	}

	for (int i = 0; i < t; i++) {
		cin >> x >> d >> k;
		MoveCircle();
		if (!MoveNum())
			CalAverage();
	}
	cout << CalSum() << endl;
}

'백준 알고리즘 > DFS' 카테고리의 다른 글

마법사 상어와 파이어스톰 C++  (0) 2021.09.22
상어 중학교 C++  (0) 2021.09.18
마법사 상어와 파이어스톰  (0) 2021.04.01
청소년 상어 C++  (0) 2021.03.08
마법사 상어와 파이어스톰 C++  (0) 2021.02.28