백준 알고리즘/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;
}