Algorithm/SWEA

[SWEA] 2806. N-Queen

benguin 2019. 4. 10. 00:39

[URL]

https://www.swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AV7GKs06AU0DFAXB&categoryId=AV7GKs06AU0DFAXB&categoryType=CODE&&&

 

SW Expert Academy

SW 프로그래밍 역량 강화에 도움이 되는 다양한 학습 컨텐츠를 확인하세요!

www.swexpertacademy.com

[풀이 과정]

1. DFS & 백트래킹 문제

2. 유망성 검토를 통하여 완전 탐색 중 백트래킹을 통하여 check하는 설정

3. 퀸 놓는 방법 map[][] == 0 인 경우 놓을 수 있다.

4. 퀸 하나를 놓을 경우 -> map[][]에 안되는 부분(가로, 세로, 대각선1, 대각선 2)을

plusOne()함수를 통해 1씩 증가

5. 백트래킹 - > 이전에 퀸을 놓으며 plusOne()함수를 통해 1씩 증가시켰던 부분을 되돌린다.

--> minusOne()함수를 통해 1씩 감소

6. 3번으로 되돌리며 퀸을 다 놓을때 까지 가능한 개수 계산

 

[소스 코드]

 

 

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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
#include <stdio.h>
 
using namespace std;
 
const int MAX = 11;
 
int N;
int map[MAX][MAX];
int dap = 0;
 
void plusONE(int r, int c) {
    for (int i = 0; i < N; i++)        // 가로 1추가
    {
        map[r][i]++;
    }
 
    for (int i = 0; i < N; i++)        // 세로 1추가, (r,c) 제외
    {
        if (i == r)
            continue;
 
        map[i][c]++;
    }
 
    for (int i = 0; i < N; i++)        // 왼쪽 아래 오른쪽 위 대각선 1추가, (r,c) 제외
    {
        if (r - i >= 0 && c - i >= 0) {
            if (r-== r && c -== c)
                continue;
            
            map[r - i][c - i]++;
        }
 
        if (r + i < N && c + i < N)
        {
            if (r + i == r && c + i == c)
                continue;
            
            map[r + i][c + i]++;
        }
    }
 
    for (int i = 0; i < N; i++)        // 왼쪽 위 오른쪽 아래 대각선 1추가, (r,c) 제외
    {
        if (r - i >= 0 && c + i < N) {
            if (r-== r && c -== c)
                continue;
 
            map[r - i][c + i]++;
        }
 
        if (r + i < N && c - i >= 0)
        {
            if (r + i == r && c + i == c)
                continue;
 
            map[r + i][c - i]++;
        }
    }
}
 
void minusONE(int r, int c) {
    for (int i = 0; i < N; i++)        // 가로 1추가
    {
        map[r][i]--;
    }
 
    for (int i = 0; i < N; i++)        // 세로 1추가, (r,c) 제외
    {
        if (i == r)
            continue;
 
        map[i][c]--;
    }
 
    for (int i = 0; i < N; i++)        // 왼쪽 아래 오른쪽 위 대각선 1추가, (r,c) 제외
    {
        if (r - i >= 0 && c - i >= 0) {
            if (r - i == r && c - i == c)
                continue;
 
            map[r - i][c - i]--;
        }
 
        if (r + i < N && c + i < N)
        {
            if (r + i == r && c + i == c)
                continue;
 
            map[r + i][c + i]--;
        }
    }
 
    for (int i = 0; i < N; i++)        // 왼쪽 위 오른쪽 아래 대각선 1추가, (r,c) 제외
    {
        if (r - i >= 0 && c + i < N) {
            if (r - i == r && c - i == c)
                continue;
 
            map[r - i][c + i]--;
        }
 
        if (r + i < N && c - i >= 0)
        {
            if (r + i == r && c + i == c)
                continue;
 
            map[r + i][c - i]--;
        }
    }
}
 
void go(int cnt)
{
    if (cnt == N)
    {
        dap++;
        return ;
    }
    /////////////////////////////////////////////////////
    for (int j = 0; j < N; j++)
    {
        if (map[cnt][j] == 0)
        {
            plusONE(cnt, j);
            cnt++;
 
            go(cnt);
 
            cnt--;
            minusONE(cnt, j);
        }        
    }
}
 
int main()
{
    int T;
    scanf("%d"&T);
    for (int tc = 0; tc < T; tc++)
    {
        dap = 0;
        scanf("%d"&N);
 
        for (int i = 0; i < N; i++)
        {
            for (int j = 0; j < N; j++)
            {
                map[i][j] = 0;
            }
        }
 
        go(0);
 
        printf("#%d %d\n", tc+1, dap);
    }
 
    return 0;
}
cs