C언어로 시작해서 실패를 맛보고
JAVA로 단련을 거듭하던 어느 날 다시 시도해봤을 때 결국 풀어낸 문제
코드를 치기 전 생각을 해야한다.
모든 상황을 고려하고 미리 설계를 한 뒤 가장 나중에 코드를 치자.
주사위의 여섯 면과 방향, 위치를 담은 객체를 만든 게 좋았던 거 같다.
굴리는 방향에 따라 어떻게 달라지는지 상상을 하는 게 안 그려졌었는데 그림도 그려보고, 문제 풀이를 여러번 해본 경험이 쌓이니까 해낼 수 있었어.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;
public class Main {
public static int[][] dr = new int[][] {{0,1,0,-1}, {1,0,-1,0}};
public static int n;
public static int m;
public static int[][] pan;
public static int result = 0;
public static class dice {
static int up = 1;
static int north = 2;
static int east = 3;
static int south = 5;
static int west = 4;
static int down = 6;
static int y = 0;
static int x = 0;
static int direc = 0;
}
public static boolean isOut(int y, int x) {
if (y < 0 || y >= n) return true;
if (x < 0 || x >= m) return true;
return false;
}
public static void rollDice() {
if (dice.direc == 0 && isOut(dice.y, dice.x+1)) dice.direc = 2;
if (dice.direc == 1 && isOut(dice.y+1, dice.x)) dice.direc = 3;
if (dice.direc == 2 && isOut(dice.y, dice.x-1)) dice.direc = 0;
if (dice.direc == 3 && isOut(dice.y-1, dice.x)) dice.direc = 1;
if (dice.direc == 0) {
dice.x++;
int temp = dice.up;
dice.up = dice.west;
dice.west = dice.down;
dice.down = dice.east;
dice.east = temp;
} else if (dice.direc == 1) {
dice.y++;
int temp = dice.up;
dice.up = dice.north;
dice.north = dice.down;
dice.down = dice.south;
dice.south = temp;
} else if (dice.direc == 2) {
dice.x--;
int temp = dice.up;
dice.up = dice.east;
dice.east = dice.down;
dice.down = dice.west;
dice.west = temp;
} else {
dice.y--;
int temp = dice.up;
dice.up = dice.south;
dice.south = dice.down;
dice.down = dice.north;
dice.north = temp;
}
}
public static void scoreCal() {
int pSco = pan[dice.y][dice.x];
if (dice.down > pSco) dice.direc = (dice.direc + 1) % 4;
else if (dice.down < pSco) dice.direc = (dice.direc + 3) % 4;
Queue<int[]> que = new LinkedList<int[]>();
boolean[][] visit = new boolean[n][m];
que.add(new int[] {dice.y, dice.x});
visit[dice.y][dice.x] = true;
int cnt = 1;
while (!que.isEmpty()) {
int[] now = que.poll();
for (int i = 0; i < 4; i++) {
int goy = now[0] + dr[0][i];
int gox = now[1] + dr[1][i];
if (isOut(goy, gox) || pan[goy][gox] != pSco || visit[goy][gox]) continue;
visit[goy][gox] = true;
que.add(new int[] {goy, gox});
cnt++;
}
}
result += cnt * pSco;
}
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st;
/*
* 1. 이동방향으로 한칸(끝칸이라면 이동방향 반대로 바꾼 후 한칸)
* 2. 도착한 칸 점수(B*주변에B영역크기) 획득
* 3. 주사위 아랫면 A 칸 B
* A>B 시계, A=B 변화 x, A<B 반시계
*/
st = new StringTokenizer(br.readLine());
n = Integer.parseInt(st.nextToken());
m = Integer.parseInt(st.nextToken());
int k = Integer.parseInt(st.nextToken()); // 이동 횟수
pan = new int[n][m];
for (int i = 0; i < n; i++) {
st = new StringTokenizer(br.readLine());
for (int j = 0; j < m; j++) {
pan[i][j] = Integer.parseInt(st.nextToken());
}
}
for (int idong = 0; idong < k; idong++) {
rollDice();
scoreCal();
}
System.out.println(result);
}
}
과거의 내가 시도했던 C언어 풀이는 아래와 같다.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <malloc.h>
int d = 1, count = 0; // 방향, 총 획득 점수
int x = 1, y = 1;
int N, M, K; // 세로, 가로, 횟수
int kount = 0; // 방문 횟수 카운트
int dice[7];
int map[21][21], dojang[21][21];
void south() {
dice[6] = dice[3];
dice[3] = dice[2];
dice[2] = dice[1];
dice[1] = dice[0];
dice[0] = dice[6];
y++;
}
void north() {
dice[6] = dice[0];
dice[0] = dice[1];
dice[1] = dice[2];
dice[2] = dice[3];
dice[3] = dice[6];
y--;
}
void east() {
dice[6] = dice[1];
dice[1] = dice[4];
dice[4] = dice[3];
dice[3] = dice[5];
dice[5] = dice[6];
x++;
}
void west() {
dice[6] = dice[1];
dice[1] = dice[5];
dice[5] = dice[3];
dice[3] = dice[4];
dice[4] = dice[6];
x--;
}
void direction() {
if (dice[3] > map[x][y]) {
if (d >= 4) d = 1;
else d++;
} else if (dice[3] < map[x][y]) {
if (d <= 1) d = 4;
else d--;
}
if (x == M && d == 1) d = 3;
if (x == 1 && d == 3) d = 1;
if (y == N && d == 2) d = 4;
if (y == 1 && d == 4) d = 2;
}
void wasd(int a, int b) {
if ((a + 1 <= M) && (dojang[a + 1][b] == 0)) {
if (map[a + 1][b] == map[x][y]) {
dojang[a + 1][b] = 1;
wasd(a + 1, b);
} else dojang[a + 1][b] = 2;
}
if ((b + 1 <= N) && (dojang[a][b + 1] == 0)) {
if (map[a][b + 1] == map[x][y]) {
dojang[a][b + 1] = 1;
wasd(a, b + 1);
} else dojang[a + 1][b] = 2;
}
if ((a - 1 >= 1) && (dojang[a - 1][b] == 0)) {
if (map[a - 1][b] == map[x][y]) {
dojang[a - 1][b] = 1;
wasd(a - 1, b);
} else dojang[a - 1][b] = 2;
}
if ((b - 1 >= 1) && (dojang[a][b - 1] == 0)) {
if (map[a][b - 1] == map[x][y]) {
dojang[a][b - 1] = 1;
wasd(a, b - 1);
} else dojang[a][b - 1] = 2;
}
}
void jumsu(int x, int y) {
for (int i = 1; i <= M; i++)
for (int j = 1; j <= N; j++)
dojang[i][j] = 0;
dojang[x][y] = 1;
wasd(x, y);
int s = 0;
for (int i = 1; i <= M; i++)
for (int j = 1; j <= N; j++)
if (dojang[i][j] == 1) s++;
count = count + s * map[x][y];
}
void game(int d) {
if (kount >= K) return;
if (d == 1) east();
else if (d == 2) south();
else if (d == 3) west();
else if (d == 4) north();
kount++;
jumsu(x, y); // 점수 획득
direction(); // 방향 설정
game(d);
}
int main() {
dice[0] = 2;
dice[1] = 1; //윗면
dice[2] = 5;
dice[3] = 6; //바닥면
dice[4] = 4; //좌
dice[5] = 3; //우
scanf("%d %d %d ", &N, &M, &K);
for (int j = 1; j <= N; j++)
for (int i = 1; i <= M; i++)
scanf("%d ", &map[i][j]);
game(1);
printf("%d", count);
getchar();
getchar();
getchar();
return 0;
}