1. 문제설명
총 25명의 여학생들이 5x5의 정사각형 격자 형태로 자리가 배치되어 있다. S(이다솜파)와 Y(임도연파)를 값으로 갖는 5*5 행렬이 주어졌을 때 아래 규칙을 만족하는 모든 경우의 수를 구한다.
- 7명의 학생들로 구성되어야 하고, 7명의 자리는 서로 가로나 세로로 인접해야 한다.
- 7명의 학생 중 S 학생이 적어도 4명 이상은 반드시 포함되어야 한다.
- 시간 제한: 2초
- 메모리 제한: 256MB
2. 접근 방식
- 25자리 중 7자리를 선택하는데, ‘S’ 학생이 4명 이상 포함되도록 한다. (조합, 백트래킹)
- BFS를 사용해 해당 7개의 자리가 모두 상하좌우로 연결되어 있는지 확인한다.
- 선택된 7명의 자리가 서로 인접한디 BFS로 확인한다. 인접할 경우 count 증가시킨다.
3. 틀린 이유
2차원 배열로 백트래킹 방법을 사용했지만 해결되지 않았다.
참고: https://c-king.tistory.com/451
4. 틀린 부분 수정
조합 방식을 사용하여 25명 중 7명을 선택하고, BFS를 통해 모두 인접한 학생인지 확인하는 방식을 사용한다.
5. 최종 코드
import java.io.*;
import java.util.*;
public class Main {
static char[][] students;
static int[] selected = new int[7]; // 선택된 학생들의 좌표 저장 (0~24로 저장)
static boolean[] visited; // 방문 처리 배열
static int count = 0; // 가능한 경우의 수
// // 상하좌우 이동을 위한 배열
static int[] dx = {-1, 1, 0, 0};
static int[] dy = {0, 0, -1, 1};
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
students = new char[5][5];
// 학생 자리 배치 정보 입력받기
for(int i=0; i<5; i++) {
students[i] = br.readLine().toCharArray();
}
// 백트래킹으로 7명의 학생 선택
backTrack(0, 0, 0);
System.out.println(count);
}
// 시작 위치, 'Y' 학생 수, 선택한 학생 수를 인자로 받음
static void backTrack(int start, int yCnt, int depth) {
// 'Y' 학생이 4명 이상이 되면 종료
if(yCnt >= 4) return;
// 7명을 선택하면 인접해있는지 검사
if(depth == 7) {
visited = new boolean[7];
bfs();
return;
}
// 0~24 중에서 7명을 선택 (5x5 배열을 1차원으로 변환하여 탐색)
// 5로 나눈 몫을 행, 나머지를 열로 설정하면 5*5 행렬 표현이 가능함
for(int i=start; i<25; i++) {
selected[depth] = i; // i번쨰 좌표 선택
if(students[i/5][i%5] == 'Y') { // 'Y' 학생일 경우
backTrack(i+1, yCnt+1, depth+1);
} else { // 'S' 학생일 경우
backTrack(i+1, yCnt, depth+1);
}
}
}
static void bfs() {
Queue<int[]> q = new ArrayDeque<>();
// 첫 번째 선택된 학생의 위치 넣기
q.offer(new int[]{selected[0]/5, selected[0]%5});
visited[0] = true; // 방문 처리
int cnt = 1; // 인접한 학생 수
while(!q.isEmpty()) {
int[] cur = q.poll();
// 상하좌우로 인접한 위치 탐색
for(int i=0; i<4; i++) {
int nx = dx[i] + cur[0];
int ny = dy[i] + cur[1];
int ni = nx*5 + ny; // 새로운 좌표를 0~24 범위로 변환
// 자리 범위 내에 있을 경우
if(nx > -1 && nx < 5 && ny > -1 && ny < 5) {
// 선택된 7개의 인덱스가 서로 연결되어있는지 검사
for(int j=0; j<7; j++) {
// 아직 방문하지 않은 학생이면
if(!visited[j] && selected[j] == ni) {
visited[j] = true; // 방문 처리
q.offer(new int[]{nx, ny}); // 큐에 추가
cnt++; // 인접한 학생 수 증가
}
}
}
}
}
// 7명의 학생이 인접해있으면 count 증가
if(cnt == 7) count++;
}
}
반응형
'알고리즘 문제 > 백준' 카테고리의 다른 글
[백준] 15685번: 드래곤 커브 (Java) (0) | 2024.09.17 |
---|---|
[백준] 5212번: 지구 온난화 (Java) (0) | 2024.09.17 |
[백준] 14888번: 연산자 끼워넣기 (Java) (0) | 2024.09.13 |
[백준] 16987번: 계란으로 계란치기 (Java) (0) | 2024.09.13 |
[백준] 1927번: N번째 큰 수 (Java) (0) | 2024.09.11 |
댓글