반응형
Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- 59412
- 핵심
- 165672
- PCCP
- SQL
- 티스토리챌린지
- 프로그래머스
- 싸피
- 10기
- 퍼즐 조각 채우기
- 설명
- 146355
- 142085
- 백준
- 수료
- 14942
- 59409
- softeer
- 후기
- 해결
- SSAFY
- 오블완
- MySQL
- 소프티어
- 진료과별 총 예약 횟수 출력하기
- java
- 정기 코딩 인증평가
- 12930
- 조건에 부합하는 중고거래 상태 구하기
- 132202
Archives
- Today
- Total
개발 쥬스
[프로그래머스/Java] 혼자서 하는 틱택토 본문
반응형
https://school.programmers.co.kr/learn/courses/30/lessons/160585
단순한 구현 문제였지만 반례를 하나 놓쳐서 고생했던 문제입니다.
고찰 과정
String[] 형태의 board를 저는 단순 Charater 형으로 바꿔서 다루고 싶었기에 cBoard를 따로 만들어 올바른 틱택토인지 판단하였습니다. 문제 해결 과정은 다음과 같습니다.
- 2차원 배열의 보드(cBoard)를 돌아보며 첫 행인 경우 또는 첫 열인 경우에는 나올 수 있는 빙고를 확인해주고 'O'에 대한 빙고의 수 및 'X'에 대한 빙고 개수를 세어준다.
- 보드에서 나온 'O'의 총 개수와 'X'의 총 개수를 세어준다.
- 나온 각 틱택토 문자의 총 개수 및 빙고수를 바탕으로 올바른 틱택토인지 판별한다.
- 'X'의 총 개수가 'O'의 총 개수보다 많으면 올바른 틱택토가 아니다.
- 'X'의 총 개수가 'O'의 총 개수보다 같고 'O'가 이긴 상황이 나온 경우 올바른 틱택토가 아니다.
- 'O'의 총 개수가 'X'의 총 개수보다 많고 'O'와 'X'의 개수 차이가 한 개보다 많거나 'X'의 빙고가 한 개 이상이거나 'O'의 빙고가 2개가 넘어가는 경우 올바른 틱택토가 아니다.
이를 바탕으로 코드를 구현하였습니다. 참고로 반례를 찾은 것 중에서 오래 걸렸던 부분이 3번의 마지막 항목이었는데 'O'의 빙고가 두 개가 나오는 경우도 가능하다는 점이었습니다. 왜냐하면 'O'가 놓인 자리가 가로, 세로, 대각선 중 두 부분이 겹쳐서 동시에 빙고 처리가 되는 경우도 나올 수가 있기 때문입니다.
코드
import java.util.*;
class Solution {
private static final int OK = 1;
private static final int NOT_OK = 0;
private static final char SPACE = '.';
public int solution(String[] board) {
int answer = OK;
char[][] cBoard = new char[3][3];
Map<Character, int[]> map = new HashMap<>();
// 문자열을 캐릭터형 2차원 배열에 담아두기
for (int i = 0; i < 3; ++i) {
cBoard[i] = board[i].toCharArray();
}
map.put('X', new int[2]); // 총 카운트, 빙고카운트
map.put('O', new int[2]);
for (int i = 0; i < 3; ++i) {
for (int j = 0; j < 3; ++j) {
if (cBoard[i][j] == SPACE) {
continue;
}
// 첫행일 때
if (i == 0) {
if (j == 0) { // 첫 열
// 가로 확인
if (cBoard[i][j] == cBoard[i][j + 1] && cBoard[i][j] == cBoard[i][j + 2]) {
++map.get(cBoard[i][j])[1];
}
// 오른아래 대각 확인
if (cBoard[i][j] == cBoard[i + 1][j + 1] && cBoard[i][j] == cBoard[i + 2][j + 2]) {
++map.get(cBoard[i][j])[1];
}
} else if (j == 2) { // 마지막 열인 경우
// 왼쪽아래 대각 확인
if (cBoard[i][j] == cBoard[i + 1][j - 1] && cBoard[i][j] == cBoard[i + 2][j - 2]) {
++map.get(cBoard[i][j])[1];
}
}
// 세로의 빙고 여부 보기
if (cBoard[i][j] == cBoard[i + 1][j] && cBoard[i][j] == cBoard[i + 2][j]) {
++map.get(cBoard[i][j])[1];
}
++map.get(cBoard[i][j])[0];
} else { // 첫행이 아닐 때 가로만
if (j == 0) {
if (cBoard[i][j] == cBoard[i][j + 1] && cBoard[i][j] == cBoard[i][j + 2]) {
++map.get(cBoard[i][j])[1];
}
}
++map.get(cBoard[i][j])[0];
}
}
}
int[] xInfo = map.get('X');
int[] oInfo = map.get('O');
if (xInfo[0] > oInfo[0]) { // X의 수가 더 많은 경우는 없다.
answer = NOT_OK;
} else if (xInfo[0] == oInfo[0]) { // x가 이기거나 진행중
if (oInfo[1] > 0) { // O의 빙고가 하나 이상 나오거나 X의 빙고가 2개 이상 나온 경우
answer = NOT_OK;
}
} else {// 무승부도 가능 -> 꽉 채웠을 때
if (oInfo[0] - xInfo[0] > 1 || xInfo[1] >= 1 || oInfo[1] > 2) {
answer = NOT_OK;
}
}
return answer;
}
}
반응형
'알고리즘' 카테고리의 다른 글
[프로그래머스/Java] 억억단을 외우자 (0) | 2024.07.31 |
---|---|
[프로그래머스/Java] 숫자 변환하기 (0) | 2024.07.31 |
[프로그래머스/Java] 아날로그 시계 (pccp 기출문제) (0) | 2024.07.29 |
[프로그래머스/Java] 표현 가능한 이진트리 (2023 카카오 블라인드 채용 기출) (0) | 2024.07.29 |
[프로그래머스/Java] 뒤에 있는 큰 수 찾기 (0) | 2024.07.27 |