BAEK_17822_원판돌리기
in Sidemenu / BaekJoon
17822. 원판돌리기
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.StringTokenizer;
public class Main {
static int R, C, N, target, dir, count, sum = 0, numCnt;
static int[][] circle, pos = { { 0, 1 }, { 0, -1 }, { 1, 0 }, { -1, 0 } };
static boolean isAdj, isZero;
static LinkedList<int[]> queue = new LinkedList<>();
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
R = toInt(st.nextToken());
C = toInt(st.nextToken());
N = toInt(st.nextToken());
circle = new int[R][C];
numCnt = R * C;
for (int i = 0; i < R; i++) {
st = new StringTokenizer(br.readLine());
for (int j = 0; j < C; j++) {
circle[i][j] = toInt(st.nextToken());
sum += circle[i][j];
}
}
for (int i = 0; i < N; i++) {
st = new StringTokenizer(br.readLine());
target = toInt(st.nextToken());
dir = toInt(st.nextToken());
count = toInt(st.nextToken());
order();
if (isZero)
break;
}
System.out.println(isZero ? 0 : sum);
}
static void order() {
for (int i = 0; i < R; i++) {
if ((i + 1) % target == 0) {
rotation(i);
}
}
isAdj = false;
for (int i = 0; i < R; i++) {
for (int j = 0; j < C; j++) {
if (circle[i][j] != 0) {
checkAdj(i, j, circle[i][j]);
}
}
}
if (!isAdj) {
calc();
}
}
static void rotation(int r) {
int idx = dir == 1 ? count % C : C - count % C;
int[] tempCircle = new int[C];
for (int i = idx; i < C; i++) {
tempCircle[i - idx] = circle[r][i];
}
for (int i = 0; i < idx; i++) {
tempCircle[i + C - idx] = circle[r][i];
}
for (int i = 0; i < C; i++) {
circle[r][i] = tempCircle[i];
}
}
static void checkAdj(int r, int c, int val) {
queue.offer(new int[] { r, c });
while (!queue.isEmpty()) {
int[] temp = queue.poll();
int tempr = temp[0];
int tempc = temp[1];
if (tempc == 0 || tempc == C - 1) {
checkPoint(tempr, tempc, val);
}
for (int i = 0; i < 4; i++) {
int nr = tempr + pos[i][0];
int nc = tempc + pos[i][1];
if (isOk(nr, nc, val)) {
erase(nr, nc, val);
}
}
}
}
static void checkPoint(int r, int c, int val) {
int key = c == 0 ? C - 1 : 0;
if (circle[r][key] == val) {
erase(r, key, val);
}
}
static void erase(int r, int c, int val) {
sum -= val;
numCnt--;
isAdj = true;
circle[r][c] = 0;
queue.offer(new int[] { r, c });
}
static void calc() {
if (sum == 0) {
isZero = true;
return;
}
float avg = (float) sum / numCnt;
for (int i = 0; i < R; i++) {
for (int j = 0; j < C; j++) {
if (circle[i][j] != 0) {
if (circle[i][j] > avg) {
circle[i][j]--;
sum--;
} else if (circle[i][j] < avg) {
circle[i][j]++;
sum++;
}
}
}
}
}
static boolean isOk(int r, int c, int val) {
return (r >= 0 && c >= 0 && r < R && c < C && circle[r][c] == val) ? true : false;
}
static int toInt(String input) {
return Integer.parseInt(input);
}
}