프로그래머스 모의테스트 마지막 문제였던 빙고 문제
솔직히 다른 알고리즘이 자신있는건 아니지만
현재 가장 자신없는 알고리즘 부분은 BFS/DFS.. 탐색!! 부분입니다.
그래서 문제로 다중 행렬 나온다음에 넓이 체크하라는거 나오면 솔직히 겁부터 나긴 합니다.
탐색 알고리즘을 완전히 이해한 후 문제를 풀려고 했으나
일단 그냥 풀어보고 싶은 알수없는 오기(?) 발동으로 빙고 문제를 풀어봤습니다.
막 풀어서 코드가 길어요..
그럼 풀어봅시다
[문제]
* 빙고는 NxN 크기의 게임 보드 칸에 1부터 NxN까지의 자연수를 중복 없이 하나씩 적은 후 숫자를 하나씩 지워나가는 게임입니다.
* 이때, 가로, 세로, 대각선 방향으로 한 줄에 적힌 숫자를 모두 지울 경우 빙고를 1개 만들었다고 합니다.
- 다음은 4X4 크기의 게임 보드를 이용해 게임을 진행한 예시입니다.
- 위와 같이 각 칸에 숫자가 적혀 있을 때, 위 게임 보드에서 순서대로 지운 숫자가 [14,3,2,4,13,1,16,11,5,15]인 경우 아래와 같이 빙고 3개가 만들어집니다.
빙고 게임 보드에 적힌 숫자가 담겨있는 배열 board, 게임 보드에서 순서대로 지운 숫자가 들어있는 배열 nums가 매개변수로 주어질 때,
board에서 nums에 들어있는 숫자를 모두 지우면 몇 개의 빙고가 만들어지는지 return하도록 solution함수를 완성해주세요.
[제한사항]
board는 게임 보드 칸에 적힌 숫자를 뜻하는 NxN크기의 2차원 배열이며, N은 2 이상 500이하의 자연수입니다.
board의 각 칸에는 1 이상 NxN이하의 자연수가 중복 없이 하나씩 들어있습니다.
nums는 board에서 지울 숫자가 들어있는 배열이며, 길이는 1 이상 NxN이하입니다.
nums에 들어있는 숫자는 1 이상 NxN이하의 자연수이며, 중복된 수가 들어있지 않습니다.
[문제 풀이]
저는 다음과 같은 순서로 문제를 풀었습니다.
1. num 배열에 있는 수를 하나씩 체크하며 보드 판에 해당 숫자가 있는지를 확인하고, 있으면 0으로 바꾸어 준다.
2. 바꾸어진 빙고판을 count_bingo() 함수로 보내어 빙고 갯수를 판별한다.
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 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 | package pracitce_note; public class mock_test03 { //빙고판 확인 함수 public static int[][] confirm_borad(int[][] b,int num) { for(int i=0; i<b.length; i++) { for(int j=0; j<b.length; j++) { //숫자 있으면 0으로 변경 if(b[i][j]==num) { b[i][j] = 0; } } } return b; } //디버깅용 출력 함수 /*public static void print(int[][] b) { for(int i=0; i<b.length; i++) { for(int j=0; j<b.length; j++) { System.out.print(b[i][j]+" "); } System.out.println(); } }*/ //빙고 카운트 public static void count_bingo(int[][] board) { //가로와 세로를 체크해 줄 V - H 배열 생성 int v[] = new int[board.length]; int h[] = new int[board.length]; int c[] = new int[2]; //대각선은 두개 뿐 int count =0; //0으로 바뀐거 체크하면서 가로 / 세로/ 대각선 체크 for(int i=0; i<board.length; i++) { for(int j=0; j<board.length; j++) { //가로 카운트 if(board[i][j]==0) { v[i]++; //가로 체크 h[j]++; //세로 체크 if(i==j) { //대각선 체크 c[0]++; } if(i+j==board.length-1) { c[1]++; } } } } //체크값 확인해서 빙고면 count++ for(int k=0; k<v.length; k++) { if(v[k] == v.length) { count++; } if(h[k] == v.length) { count++; } } //대각선은 어떤 빙고판이든 2개라서.. 따로 빼서 체크.. if(c[0]==v.length) { count++; } if(c[1]==v.length) { count++; } //count 값 System.out.println(count); } public static void main(String[] args) { // TODO Auto-generated method stub int[][] board = {{11,13,15,16},{12,1,4,3},{10,2,7,8},{5,14,6,9}}; int[] num = {14,3,2,4,13,1,16,11,5,15}; /* solution * 1. num에 있는 숫자를 하나씩 비교하며 board에 있는경우 0으로 바꾼다 * 2. 바꾸어진 board에 빙고 부분을 카운트 한다. * */ //num 하나씩 보내면서 체크하기 for(int i=0; i<num.length; i++) { confirm_borad(board,num[i]); } //print(board); count_bingo(board); //빙고 체크하기 } } |
효율성은 O(2n^2)? 되는거같은뎅
풀고보니 num 체크하면서 바로바로 카운트하면 함수를 두개로 나눌 필요가 없어보이긴 합니다
근거없는 자신감이지만 탐색 알고리즘을 공부하고나면 코드가 엄청 줄고 효울성도 올라갈 것 같은 기분이 ㅋㅋ
빨리 탐색 알고리즘 공부를 해야겠네요
'알고리즘 공부 > 알고리즘 문제' 카테고리의 다른 글
나누어 떨어지는 숫자 배열 (0) | 2019.03.12 |
---|---|
문자열 내 맘대로 정렬하기 (0) | 2019.03.12 |
배열 회전 결과값 확인하기 (1) | 2019.01.26 |
도로에 가로등 전구 달기 (0) | 2019.01.26 |
숫자를 한글로 읽기 (0) | 2019.01.06 |