[백준] 2578 빙고

jyleever·2022년 7월 25일
0

알고리즘

목록 보기
15/26

문제

https://www.acmicpc.net/problem/2578

풀이

문제 및 조건

5x5 빙고 판에 쓴 수들과 사회자가 부르는 수의 순서가 주어지며 수를 하나씩 지울 때 사회자가 몇 번째 수를 부른 후 철수가 "빙고"를 외치게 되는가?

조건

  • 1개의 선이 세 개 이상 그어지는 순간 "빙고"라고 외친다.

입력

5x5 2차원 int 배열
사회자가 부르는 수 int
모든 입력의 범위는 [1,25]

출력

int 1글자

풀이

빙고가 될 조건

  • 행은 같은데 열이 0부터 4까지 동일한 5개의 좌표값이 0이어야 한다.
  • 열은 같은데 행이 0부터 4까지 동일한 5개의 좌표값이 0이어야 한다.
  • 행과 열이 같은 5개의 좌표 값이 0이어야 한다.
  • 행과 열의 합이 4인 좌표 값이 0이어야 한다.

문제 순서

  1. 배열을 생성한다.
  2. 숫자가 입력될 때마다 해당 위치를 0으로 바꿔준다.
  3. 1개의 선이 세 개 이상 그어지는 순간 빙고이므로 숫자가 15개 불려졌을 때부터 빙고 확인 -> 아님~!!!!
    예를 들어 모서리에 있는 값의 경우 가로 줄과 세로 줄에 동시에 걸쳐져서 한 번에 2개가 빙고 됨!
    따라서 15개 이하일 때 빙고가 3개 나올 수 있기 때문에 15개 이상이라는 조건을 추가하지 않는다!
  4. 빙고 확인
  5. 0의 값이 5개가 될 때마다 빙고를 세는 숫자도 1씩 올라간다.

코드

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

/**
 * 
 * @author juyoung
 *
 *
 **빙고가 될 조건**
- 행은 같은데 열이 0부터 4까지인 5개의 좌표값이 0이어야 한다.
- 열은 같은데 행이 0부터 4까지인 5개의 좌표값이 0이어야 한다.
- 행과 열이 같은 5개의 좌표 값이 0이어야 한다.
- 행과 열의 합이 4인 좌표 값이 0이어야 한다.
 */
public class Main {
	
		static int[][] board;
		static int bingo;// 빙고 개수
		static int cnt; // 확인한 값의 개수
		
	public static void main(String[] args) throws IOException {
		
		board = new int[5][5];
		bingo = 0;
		cnt = 0;
		final int BINGOCALL = 3;
		
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st;
		
		// 1. 배열 생성
		for(int i=0; i<5; i++) {
			st = new StringTokenizer(br.readLine(), " ");
			for(int j=0; j<5; j++) {
				board[i][j] = Integer.parseInt(st.nextToken());
			}
		}
		
		// 2. 숫자가 불릴 때마다 해당 값을 가진 좌표를 찾아 0으로 값을 바꿔준다
		loop:for(int i=0; i<5; i++) {
			st = new StringTokenizer(br.readLine(), " ");
			
			for(int j=0; j<5; j++) {
				int tmp = Integer.parseInt(st.nextToken());
				
				// 사회자가 부른 숫자 지움
				for(int k=0; k<5; k++) {
					for(int l=0; l<5; l++) {
						if(board[k][l] == tmp) {
							board[k][l] = 0; // 사회자가 부른 숫자 지움
							cnt++;
						}
					}
				}
                
				rCheck();
				cCheck();
				rightCheck();
				leftCheck();
				
                // 정확히 3개가 안 나올 수도 있음.
                // 반례 : 모서리에 있는 값의 경우 가로 줄과 세로 줄에 동시에 걸쳐져서 한 번에 2개가 빙고 됨!
				if(bingo >= BINGOCALL) break loop;
				else bingo = 0; // 그 다음 숫자를 확인할 때에는 빙고 갯수 초기화!!!
			}
			
		}
		
		System.out.println(cnt);
	}
	
	// 행은 같은데 열이 0부터 4까지인 5개의 좌표값이 0인 경우
	public static void rCheck() {
		for(int i=0; i<5; i++) {
			
			int tmpCnt = 0; // 5가 되면 빙고
			for(int j=0; j<5; j++) {
				if(board[i][j] == 0) {
					tmpCnt++;
				}
			}
			if(tmpCnt == 5) bingo++;
		}

	}

	// 열은 같은데 행이 0부터 4까지인 5개의 좌표값이 0인 경우
	public static void cCheck() {
		for(int i=0; i<5; i++) {
			
			int tmpCnt = 0; // 5가 되면 빙고
			for(int j=0; j<5; j++) {
				if(board[j][i] == 0) {
					tmpCnt++;
				}
			}
			if(tmpCnt == 5) bingo++;
		}
	}
	
	// 왼쪽에서 오른쪽으로 가는 대각선 확인
	public static void rightCheck() {
		int tmpCnt = 0; // 5가 되면 빙고
		for(int i=0; i<5; i++) {
			if(board[i][i] == 0) tmpCnt++;
		}
		if(tmpCnt == 5) bingo++;
	}
	
	// 오른쪽에서 왼쪽으로 가는 대각선 확인
	public static void leftCheck() {
		int tmpCnt = 0; // 5가 되면 빙고
		for(int i=0; i<5; i++) {
			if(board[i][4-i] == 0) tmpCnt++;
		}
		if(tmpCnt == 5) bingo++;
	}
}

0개의 댓글