Notice
Recent Posts
Link
반응형
All :L
[SWEA/Java] 추억의 2048 게임(6190) 본문
반응형
https://swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AWbrg9uabZsDFAWQ
SW Expert Academy
SW 프로그래밍 역량 강화에 도움이 되는 다양한 학습 컨텐츠를 확인하세요!
swexpertacademy.com
1. 문제 분석
문제 개요:
2048 게임에서 보드의 숫자들을 이동시키고 합치는 문제입니다. 주어진 방향(왼쪽, 오른쪽, 위, 아래)으로 모든 숫자들을 이동시키고 합쳐야 합니다. 각 숫자는 같은 숫자와 합쳐지며, 합쳐진 숫자는 이동 후 새로운 숫자가 됩니다.
입력 형식:
- 첫 줄에 테스트 케이스의 수 T가 주어진다.
- 각 테스트 케이스는 다음과 같은 형식이다.
- 첫 줄에 보드의 크기 N과 이동 방향이 주어진다.
- 다음 N줄에 보드의 상태가 주어진다. 각 줄은 N개의 정수로 구성된다.
출력 형식:
- 각 테스트 케이스에 대해, 이동 후의 보드를 출력한다.
2. 알고리즘 종류
해당 문제는 "구현 및 시뮬레이션" 문제입니다. 각 방향에 대해 다음과 같은 작업을 수행합니다:
- 왼쪽: 숫자를 왼쪽으로 이동시키고 합칩니다.
- 오른쪽: 숫자를 오른쪽으로 이동시키고 합칩니다.
- 위쪽: 숫자를 위쪽으로 이동시키고 합칩니다.
- 아래쪽: 숫자를 아래쪽으로 이동시키고 합칩니다.
이 문제는 큐(Queue) 및 스택(Stack) 을 사용하여 구현됩니다. 각 방향에 따라 숫자들을 큐 또는 스택에 저장하고, 이를 통해 숫자들을 이동시키고 합치는 작업을 수행합니다.
3. 주요 부분 및 코드 작성 방법
1. 방향 처리:
- 각 방향(왼쪽, 오른쪽, 위, 아래)에 대해 별도의 메서드를 작성하여 처리합니다.
2. 큐와 스택의 사용:
- 왼쪽 및 위쪽: Queue를 사용하여 숫자를 왼쪽 또는 위쪽으로 이동시키며, 숫자가 같은 경우 합칩니다.
- 오른쪽 및 아래쪽: Stack을 사용하여 숫자를 오른쪽 또는 아래쪽으로 이동시키며, 숫자가 같은 경우 합칩니다.
3. left() 메서드:
- 각 줄의 숫자를 큐에 추가하여 왼쪽으로 이동시키고 합칩니다.
- 큐를 이용해 숫자를 왼쪽으로 정렬하고 합칩니다.
- 최종 결과를 answer 배열에 저장합니다.
4. right() 메서드:
- 각 줄의 숫자를 스택에 추가하여 오른쪽으로 이동시키고 합칩니다.
- 스택을 사용해 숫자를 오른쪽으로 정렬하고 합칩니다.
- 최종 결과를 answer 배열에 저장합니다.
5. up() 메서드:
- 각 열의 숫자를 큐에 추가하여 위쪽으로 이동시키고 합칩니다.
- 큐를 이용해 숫자를 위쪽으로 정렬하고 합칩니다.
- 최종 결과를 answer 배열에 저장합니다.
6. down() 메서드:
- 각 열의 숫자를 스택에 추가하여 아래쪽으로 이동시키고 합칩니다.
- 스택을 사용해 숫자를 아래쪽으로 정렬하고 합칩니다.
- 최종 결과를 answer 배열에 저장합니다.
4. 코드 설명
왼쪽 이동 (left()):
public static void left() { Queue<Integer> q = new LinkedList<>(); Queue<Integer> newQ = new LinkedList<>(); for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { if (Board[i][j] != 0) q.add(Board[i][j]); } while (!q.isEmpty()) { if (q.size() == 1) { newQ.add(q.poll()); break; } int n = q.poll(); if (n == q.peek()) { int sum = n + q.poll(); newQ.add(sum); } else { newQ.add(n); } } int k = 0; while (!newQ.isEmpty()) { answer[i][k++] = newQ.poll(); } } }
- Queue를 사용하여 숫자들을 왼쪽으로 이동시키고, 같은 숫자는 합칩니다.
- 처리된 결과를 answer 배열에 저장합니다.
오른쪽 이동 (right()):
public static void right() { Stack<Integer> s = new Stack<>(); Stack<Integer> newS = new Stack<>(); for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { if (Board[i][j] != 0) s.add(Board[i][j]); } while (!s.isEmpty()) { if (s.size() == 1) { newS.add(s.pop()); break; } int n = s.pop(); if (n == s.peek()) { int sum = n + s.pop(); newS.add(sum); } else { newS.add(n); } } int k = 0; while (!newS.isEmpty()) { answer[i][N - newS.size()] = newS.pop(); } } }
- Stack을 사용하여 숫자들을 오른쪽으로 이동시키고, 같은 숫자는 합칩니다.
- 처리된 결과를 answer 배열에 저장합니다.
위쪽 이동 (up()):
public static void up() { Queue<Integer> q = new LinkedList<>(); Queue<Integer> newQ = new LinkedList<>(); for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { if (Board[j][i] != 0) q.add(Board[j][i]); } while (!q.isEmpty()) { if (q.size() == 1) { newQ.add(q.poll()); break; } int n = q.poll(); if (n == q.peek()) { int sum = n + q.poll(); newQ.add(sum); } else { newQ.add(n); } } int k = 0; while (!newQ.isEmpty()) { answer[k++][i] = newQ.poll(); } } }
- Queue를 사용하여 숫자들을 위쪽으로 이동시키고, 같은 숫자는 합칩니다.
- 처리된 결과를 answer 배열에 저장합니다.
아래쪽 이동 (down()):
public static void down() { Stack<Integer> s = new Stack<>(); Stack<Integer> newS = new Stack<>(); for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { if (Board[j][i] != 0) s.add(Board[j][i]); } while (!s.isEmpty()) { if (s.size() == 1) { newS.add(s.pop()); break; } int n = s.pop(); if (n == s.peek()) { int sum = n + s.pop(); newS.add(sum); } else { newS.add(n); } } int k = 0; while (!newS.isEmpty()) { answer[N - newS.size()][i] = newS.pop(); } } }
- Stack을 사용하여 숫자들을 아래쪽으로 이동시키고, 같은 숫자는 합칩니다.
- 처리된 결과를 answer 배열에 저장합니다.
5. 전체 코드
package SWEA6109_240821; import java.io.*; import java.util.*; public class Solution { static int N; static int[][] Board, answer; public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); int T = Integer.parseInt(br.readLine()); for(int tc = 1; tc <= T; tc++) { StringTokenizer st = new StringTokenizer(br.readLine()); N = Integer.parseInt(st.nextToken()); String direction = st.nextToken(); Board = new int[N][N]; answer = new int[N][N]; for(int i = 0; i < N; i++) { st = new StringTokenizer(br.readLine(), " "); for(int j = 0; j < N; j++) Board[i][j] = Integer.parseInt(st.nextToken()); } if(direction.equals("left")) left(); else if(direction.equals("right")) right(); else if(direction.equals("up")) up(); else if(direction.equals("down")) down(); System.out.println("#" + tc); for(int i = 0; i < N; i++) { for(int j = 0; j < N; j++) System.out.print(answer[i][j] + " "); System.out.println(); } } } public static void left() { Queue<Integer> q = new LinkedList<>(); Queue<Integer> newQ = new LinkedList<>(); for(int i = 0; i < N; i++) { // 줄 별 계산 int cnt = 0; for(int j = 0; j < N; j++) { // 각 줄의 숫자 q에 추가 if(Board[i][j] != 0) q.add(Board[i][j]); // System.out.println(q); } while(!q.isEmpty()) { // q가 빌 때까지 반복 if(q.size() == 1) { newQ.add(q.poll()); break; } int n = q.poll(); if(n == q.peek()) { // 같은 숫자를 만나면 int sum = n + q.poll(); newQ.add(sum); // 합치기 } else { newQ.add(n); } } // System.out.println("test : " + newQ); int k = 0; while(!newQ.isEmpty()) { answer[i][k++] = newQ.poll(); } } } public static void right() { Stack<Integer> s = new Stack<>(); Stack<Integer> newS = new Stack<>(); for(int i = 0; i < N; i++) { // 줄 별 계산 int cnt = 0; for(int j = 0; j < N; j++) { // 각 줄의 숫자 q에 추가 if(Board[i][j] != 0) s.add(Board[i][j]); // System.out.println(s); } while(!s.isEmpty()) { // s가 빌 때까지 반복 if(s.size() == 1) { newS.add(s.pop()); break; } int n = s.pop(); if(n == s.peek()) { // 같은 숫자를 만나면 int sum = n + s.pop(); newS.add(sum); // 합치기 } else { newS.add(n); } } // System.out.println("test : " + newS); int k = 0; while(!newS.isEmpty()) { answer[i][N - newS.size()] = newS.pop(); } } } public static void up() { Queue<Integer> q = new LinkedList<>(); Queue<Integer> newQ = new LinkedList<>(); for(int i = 0; i < N; i++) { // 줄 별 계산 int cnt = 0; for(int j = 0; j < N; j++) { // 각 줄의 숫자 q에 추가 if(Board[j][i] != 0) q.add(Board[j][i]); // System.out.println(q); } while(!q.isEmpty()) { // q가 빌 때까지 반복 if(q.size() == 1) { newQ.add(q.poll()); break; } int n = q.poll(); if(n == q.peek()) { // 같은 숫자를 만나면 int sum = n + q.poll(); newQ.add(sum); // 합치기 } else { newQ.add(n); } } // System.out.println("test : " + newQ); int k = 0; while(!newQ.isEmpty()) { answer[k++][i] = newQ.poll(); } } } public static void down() { Stack<Integer> s = new Stack<>(); Stack<Integer> newS = new Stack<>(); for(int i = 0; i < N; i++) { // 줄 별 계산 int cnt = 0; for(int j = 0; j < N; j++) { // 각 줄의 숫자 q에 추가 if(Board[j][i] != 0) s.add(Board[j][i]); // System.out.println(s); } while(!s.isEmpty()) { // s가 빌 때까지 반복 if(s.size() == 1) { newS.add(s.pop()); break; } int n = s.pop(); if(n == s.peek()) { // 같은 숫자를 만나면 int sum = n + s.pop(); newS.add(sum); // 합치기 } else { newS.add(n); } } // System.out.println("test : " + newS); int k = 0; while(!newS.isEmpty()) { answer[N - newS.size()][i] = newS.pop(); } } } }
반응형
'CODING > SWEA' 카테고리의 다른 글
[SWEA/Java] 나무 높이 (14510) (0) | 2024.09.12 |
---|---|
[SWEA/Java] 디저트 카페 (2105) (0) | 2024.09.11 |
[SWEA/Java] 프로세서 연결하기 (1767) (0) | 2024.08.25 |
[SWEA/Java] 정사각형 방(1861) (0) | 2024.08.22 |