YataNox
[Java] 3085 사탕 게임 본문
문제
문제
상근이는 어렸을 적에 "봄보니 (Bomboni)" 게임을 즐겨했다.
가장 처음에 N×N크기에 사탕을 채워 놓는다.
사탕의 색은 모두 같지 않을 수도 있다.
상근이는 사탕의 색이 다른 인접한 두 칸을 고른다.
그 다음 고른 칸에 들어있는 사탕을 서로 교환한다.
이제, 모두 같은 색으로 이루어져 있는 가장 긴 연속 부분(행 또는 열)을 고른 다음 그 사탕을 모두 먹는다.
사탕이 채워진 상태가 주어졌을 때, 상근이가 먹을 수 있는 사탕의 최대 개수를 구하는 프로그램을 작성하시오.
입력
첫째 줄에 보드의 크기 N이 주어진다. (3 ≤ N ≤ 50)
다음 N개 줄에는 보드에 채워져 있는 사탕의 색상이 주어진다. 빨간색은 C, 파란색은 P, 초록색은 Z, 노란색은 Y로 주어진다.
사탕의 색이 다른 인접한 두 칸이 존재하는 입력만 주어진다.
출력
첫째 줄에 상근이가 먹을 수 있는 사탕의 최대 개수를 출력한다.
요약하자면 인접한 다른 캔디 위치를 교환했을 때 가장 긴 한 줄이 얼마냐라는 것이다.
별다른 자료구조를 활용하는 것이 아닌 일일이 확인할 수 밖에 없는 브루트 포스 문제이다.
확인을 위해 첫 번째 자리 부터 오른쪽, 아랫쪽을 한 번씩 교환해보면서 확인하는 방식을 차용한다.
위나 왼쪽을 확인할 필요는 없다. 오른쪽과 아랫쪽을 교환했을 때 이미 확인된 위치이기 때문이다.
XYY YXY
YYX 라고 가정했을 때 YYX 로 바꿨다고 해보자 (첫 행의 첫 열 X를 기준으로 오른쪽 Y와 교환)
이후 첫 행의 두 열 Y를 왼쪽의 X와 교환해봐야 이미 비교했었기 때문에 의미가 없다는 의미)
문제 풀이
1. 입력받은 숫자 크기 만큼의 이차원 Char 배열을 생성한다.
2. 한 줄 한 줄 입력받은 문자열을 한 글자씩 배열에 삽입한다.
3. [0][0] 자리의 글자부터 오른쪽 글자와 교환해간다.
4. 이때 한 번 교환할 때마다 가장 길게 이어지는 행이나 열이 얼마인지 확인하고 기록한다.
5. 해당 작업이 종료된 뒤 교환한 글자들을 기존 자리로 되돌리고 다음 열의 글자부터 다시 3을 반복한다.
6. 오른쪽 방향으로의 검사가 끝난 뒤 같은 방식으로 아랫쪽 글자와도 비교해간다.
7. 마지막으로 기록된 최대 길이를 출력한다.
자바 코드
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Main {
private static int max = 1;
private static int size;
private static char[][] board;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
size = Integer.parseInt(br.readLine());
board = new char[size][size];
// 보드에 캔디 삽입
for(int i = 0; i < size; i++){
String candyLine = br.readLine();
for(int j = 0; j < size; j++){
board[i][j] = candyLine.charAt(j);
}
}
// 행 기준 오른쪽과 변경
for(int i = 0; i < size; i++){
for(int j = 0; j < size -1; j++){
// 오른쪽 열과 변경
candySwap(i, j, i, j + 1);
// 최대 연결 캔디 검사
searchMaxCandy();
// 변경한 열 다시 되돌리기
candySwap(i , j + 1, i, j);
}
}
// 행 기준 아래쪽과 변경
for(int i = 0; i < size - 1; i++){
for(int j = 0; j < size; j++){
// 아랫쪽 행과 변경
candySwap(i, j, i + 1, j);
// 최대 연결 캔디 검사
searchMaxCandy();
// 변경한 행 다시 되돌리기
candySwap(i + 1 , j, i, j);
}
}
System.out.println(max);
}
private static void candySwap(int beforeX, int beforeY, int afterX, int afterY){
char temp = board[beforeX][beforeY];
board[beforeX][beforeY] = board[afterX][afterY];
board[afterX][afterY] = temp;
}
private static void searchMaxCandy(){
for(int i = 0; i < size; i++){
int count = 1;
for(int j = 0; j < size - 1; j++){
if(board[i][j] == board[i][j + 1])
max = Math.max(++count, max);
else
count = 1;
}
}
for(int i = 0; i < size; i++){
int count = 1;
for(int j = 0; j < size - 1; j++){
if(board[j][i] == board[j + 1][i])
max = Math.max(++count, max);
else
count = 1;
}
}
}
}
'코딩 테스트 > BAEKJOON' 카테고리의 다른 글
[Java] 18290 NM과 K (0) | 2024.03.28 |
---|---|
[Java] 6064 카잉 달력 (0) | 2024.03.28 |
[Java] 1476 날짜 계산 (1) | 2024.03.28 |
[Java] 골드바흐의 추측 (0) | 2024.03.26 |
[Java] 1929 소수 구하기 (0) | 2024.03.26 |