문제링크 : https://www.acmicpc.net/problem/9663
아이디어
- 퀸이 놓는 위치를 백트래킹 하자
- 그냥 할 경우 시간복잡도가 어마어마하게 큼
- O(N^2^(N^2)) : 225^225
- 그래서 가지를 쳐가면서 백트래킹 시작
- 퀸이기 때문에 한번에 한줄씩 밖에 안들어감
- 한줄씩 백트래킹 수행
- 세로의 경우 추후 별도 배열 만들어서 중복체크 해주자
시간복잡도 계산
- 한줄에 하나씩 들어가는 백트래킹이므로
- O(N^N) = 15^15
- 시간초과 날것 같지만
- 중간 중간 가지를 칠 것으로 예상하며 해보자
자료구조
- bool column[15] : 해당 컬럼에 퀸 있는지 체크
- 경우의 수 : cnt
- 최대 15^15 될수도 있으므로, 혹시 모르니 long long으로 사용
- 전체 맵 bool map[15][15]
코드(C++)
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 | #include <iostream> using namespace std; typedef long long ll; bool map[20][20]; bool column[20]; int N; ll cnt; bool diagonalChk(int y, int x) { // 왼쪽 대각선 int j = y; int i = x; while(j>=0 && i >=0) { if(map[j][i]) return 1; j--; i--; } // 오른쪽 대각선 j = y; i = x; while(j>=0 && i < N) { if(map[j][i]) return 1; j--; i++; } return 0; } void dfs(int y) { if(y==N) { // N개를 놓는 경우 cnt 증가 cnt++; return; } for(int i=0; i<N; i++) { if(column[i]) continue; if(diagonalChk(y,i) == true) continue; column[i] = 1; map[y][i] = 1; dfs(y+1); column[i] = 0; map[y][i] = 0; } } int main() { // 초기화 fill(column, column+20, 0); fill(&map[0][0], &map[19][20], 0); cnt=0; cin >> N; dfs(0); cout << cnt << '\n'; return 0; } | cs |
문제유형
- 백트래킹 - 2차원 경우의수
비슷한 문제
'알고리즘 > 백준' 카테고리의 다른 글
백준 14499 주사위 굴리기 (0) | 2021.03.17 |
---|---|
백준 1062 가르침 (0) | 2021.03.17 |
백준 2293 동전 1 (0) | 2021.03.16 |
백준 15663 N과 M (9) (0) | 2021.03.15 |
백준 15652 N과 M (4) (0) | 2021.03.15 |