https://www.acmicpc.net/problem/12100
12100번: 2048 (Easy)
첫째 줄에 보드의 크기 N (1 ≤ N ≤ 20)이 주어진다. 둘째 줄부터 N개의 줄에는 게임판의 초기 상태가 주어진다. 0은 빈 칸을 나타내며, 이외의 값은 모두 블록을 나타낸다. 블록에 쓰여 있는 수는 2
www.acmicpc.net
저는 해당 문제를 BFS를 이용하여 문제를 해결하였습니다.
저는 각 방향을 이동할 때 while문을 통해 해당 배열이 0이 아닐때 까지 그 방향으로 가도록 하였습니다. 이때 방향의 맨 끝에 있는 것 부터 이동시켰습니다. 위쪽이라면 맨 위에 있는 것부터 이동시키고 왼쪽으로 이동시킨다면 맨 왼쪽의 것부터 이동시켰습니다. 한번 합쳐진 것은 그때 합쳐지면 안되기 때문에 boolean 을 통해 해당 값이 이번에 합쳐졌는지를 확인하였습니다.
package BOJ.Simulation;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.function.Function;
public class BOJ_12100 {
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
Function<String,Integer> stoi = Integer::parseInt;
int n = stoi.apply(st.nextToken());
int[][] map = new int[n][n];
for(int i = 0 ; i < n ; i++){
st = new StringTokenizer(br.readLine());
for(int j = 0 ; j < n ; j++){
map[i][j] = stoi.apply(st.nextToken());
}
}
System.out.println(bfs(map,n));
}
private static int bfs(int[][] map, int n) {
Queue<int[][]> q = new LinkedList<>();
q.offer(map);
Set<String> visited = new HashSet<>();
int result = 0;
int time = 0;
q.offer(map);
while(!q.isEmpty()){
int size = q.size();
for(int s = 0 ; s < size ; s++){
int[][] now = q.poll();
// System.out.println("time:"+time+" "+Arrays.deepToString(now));
result = Math.max(checkMaxValue(now,n),result);// 0 - 처음
for(int i = 0 ; i < 2; i++){
int[][] temp = moveUpOrRight(now,n,i);
// System.out.println(i+" "+Arrays.deepToString(temp));
if(!visited.contains(Arrays.deepToString(temp))){
q.offer(temp);
}
}
for(int i = 2; i < 4; i++){
int[][] temp = moveDownOrLeft(now,n,i);
// System.out.println(i+" "+Arrays.deepToString(temp));
if(!visited.contains(Arrays.deepToString(temp))){
q.offer(temp);
}
}
}
if(time == 5){
break;
}
time++;
}
return result;
}
private static int checkMaxValue(int[][] arr , int n){
int result = 0;
for(int i = 0 ; i < n ; i++){
for(int j = 0 ; j < n ; j++){
result = Math.max(result,arr[i][j]);
}
}
return result;
}
private static final int[] dy = {-1,0,1,0};
private static final int[] dx = {0,-1,0,1};
private static int[][] moveUpOrRight(int[][] arr , int n , int dir){
int[][] temp = arrCopy(arr,n);
boolean[][] used = new boolean[n][n];
for(int i = 0 ; i < n ; i++){
for(int j = 0 ; j < n ; j++){
if(arr[i][j] != 0){
move(temp,n,i,j,dir,used);
}
}
}
return temp;
}
private static int[][] moveDownOrLeft(int[][] arr , int n , int dir){
int[][] temp = arrCopy(arr,n);
boolean[][] used = new boolean[n][n];
for(int i = n-1 ; i >= 0 ; i--){
for(int j = n-1 ; j >= 0 ; j--){
if(arr[i][j] != 0){
move(temp,n,i,j,dir,used);
}
}
}
return temp;
}
private static void move(int[][]arr , int n , int y, int x,int dir,boolean[][] used){
int ny = y + dy[dir];
int nx = x + dx[dir];
while(nx >= 0 && nx < n && ny >= 0 && ny < n && arr[ny][nx] == 0){
ny += dy[dir];
nx += dx[dir];
}
if(nx >= 0 && nx < n && ny >= 0 && ny < n && arr[y][x] == arr[ny][nx] && !used[ny][nx]){
arr[ny][nx] *= 2;
arr[y][x] = 0;
used[ny][nx] = true;
return ;
}
ny -= dy[dir];
nx -= dx[dir];
if(ny != y || nx != x){
arr[ny][nx] = arr[y][x];
arr[y][x] = 0;
}
return ;
}
private static int[][] arrCopy(int[][] arr , int n){
int[][]temp = new int[n][n];
for(int i = 0 ; i < n ; i++){
for(int j = 0 ; j < n ; j++){
temp[i][j] = arr[i][j];
}
}
return temp;
}
}
'알고리즘' 카테고리의 다른 글
백준 14502번 연구소 (JAVA) (0) | 2022.03.23 |
---|---|
백준 14500번 테트로미노 (JAVA) (0) | 2022.03.22 |
백준 13460번 구슬 탈출2 (JAVA) (0) | 2022.03.20 |
백준 1944번 복제 로봇 (JAVA) (0) | 2022.03.19 |
백준 2568번 전깃줄 - 2 (JAVA) (0) | 2022.03.19 |