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

원판 돌리기 C++

by paysmile 2021. 2. 28.
#include <iostream>
#include <cstring>

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

void copycircle() {
	memset(temp, -1, sizeof(temp));

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

//시계방향 d:0
void rotate_r() {
	copycircle();

	for (int i = 1; i * x <= n; i++) {
		for (int j = 1; j <= m; j++) {
			int index = j;
			index += k;
			while (index > m)
				index -= m;
			circle[i*x][index] = temp[i*x][j];
		}
	}
}

//반시계방향 d:1
void rotate_l() {
	copycircle();

	for (int i = 1;i*x <=n;i++) {
		for (int j = 1; j <= m; j++) {
			int index = j;
			index -= k;
			while (index <= 0)
				index += m;
			circle[i*x][index] = temp[i*x][j];
		}
	}
}

bool leftnum() {
	bool flag = false;

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

	return flag;
}

void dfs(int i, int j) {
	int movei, movej;

	for (int k = 0; k < 4; k++) {
		if (i == 1 && k == 2)
			continue;
		if (i == n && k == 3)
			continue;
		movei = i + mv[k].x;
		movej = j + mv[k].y;

		if (movei == 0) movei = n;
		if (movej == 0) movej = m;
		if (movei > n) movei = 1;
		if (movej > m) movej = 1;

		if (temp[movei][movej] == temp[i][j] && visited[movei][movej] == -1) {
			same = true;
			visited[movei][movej] = 1;
			circle[movei][movej] = 0;
			circle[i][j] = 0;
			dfs(movei, movej);
		}
	}
}

bool near() {
	memset(visited, -1, sizeof(visited));

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

	return same;
}

void changenum() {
	double average = 0;
	int count = 0;

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

	average = average / count;

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

int main(void) {
	int answer = 0;

	cin >> n >> m >> t;

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

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

		//회전
		if (d == 0)
			rotate_r();
		else
			rotate_l();

		//printcircle();

		//수가 남았는지 확인
		if (leftnum()) {
			//인접한 수 찾기
			same = false;
			copycircle();
			if (!near())
				changenum();
		}

		//printcircle();
	}

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

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

마법사 상어와 파이어스톰 C++  (0) 2021.02.28
마법사 상어와 파이어스톰 C++  (0) 2021.02.28
백준 감시 C++  (0) 2019.10.19
백준 사다리 조작 C++  (0) 2019.10.19
백준 미세먼지 안녕 C++  (0) 2019.10.15