λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°
λ°±μ€€/Gold

[BOJ] 1799 : λΉ„μˆ

by Jaeguk 2022. 1. 19.
문제 링크

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

 

1799번: λΉ„μˆ

첫째 쀄에 체슀판의 크기가 주어진닀. 체슀판의 ν¬κΈ°λŠ” 10μ΄ν•˜μ˜ μžμ—°μˆ˜μ΄λ‹€. λ‘˜μ§Έ 쀄뢀터 μ•„λž˜μ˜ μ˜ˆμ™€ 같이 체슀판의 각 칸에 λΉ„μˆμ„ 놓을 수 μžˆλŠ”μ§€ μ—†λŠ”μ§€μ— λŒ€ν•œ 정보가 체슀판 ν•œ 쀄 λ‹¨μœ„λ‘œ

www.acmicpc.net

λ°±νŠΈλž˜ν‚Ήμ— κ΄€ν•œ λ¬Έμ œλ‹€.

풀이

처음 문제λ₯Ό μ½μ—ˆμ„ λ•Œ μ™œ 이게 κ³¨λ“œ1 λ‚œμ΄λ„μ˜ 문제일까? λΌλŠ” 의문이 λ“€μ—ˆλ‹€. λΉ„μˆμ΄ λ“€μ–΄κ°ˆ μœ„μΉ˜λŠ” μ •ν•΄μ Έμžˆκ³  거기에 λΉ„μˆμ΄

1. λ†“μ΄κ±°λ‚˜

2. μ•ˆλ†“μ΄κ±°λ‚˜ λ‘˜ 쀑 ν•˜λ‚˜λ‹€.

λΉ„μˆμ΄ 놓일 수 μžˆλŠ” λͺ¨λ“  μœ„μΉ˜λ₯Ό 벑터에 μ €μž₯ν•œ λ’€ κ·Έ μœ„μΉ˜λ₯Ό λ°±νŠΈλž˜ν‚ΉμœΌλ‘œ λͺ¨λ‘ λŒλ©΄μ„œ depthκ°€ λΉ„μˆμ΄ 놓일 수 μžˆλŠ” λͺ¨λ“  칸의 κ°œμˆ˜μ™€ 같아지면 κ·Έλ•Œ μ²΄μŠ€νŒμ— λ†“μ—¬μžˆλŠ” 체슀의 개수 쀑 μ΅œλŒ€κ°’μ„ 좜λ ₯ν•˜λ©΄ λ˜κ² κ΅¬λ‚˜ 라고 μƒκ°ν–ˆλ‹€. μ‹œκ°„λ„ 10초면 λ„‰λ„‰ν•œ νŽΈμ΄λ‹ˆ λ°”λ‘œ μ½”λ“œλ₯Ό μ§°λ‹€.

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
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstdio>
#include <string.h>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <climits>
#include <algorithm>
#include <tuple>
#include <cmath>
using namespace std;
typedef long long ll;
int N;
const int MAX_N = 10 + 3;
int chess[MAX_N][MAX_N];
vector<pair<int,int>> cango; // λΉ„μˆμ΄ 놓일 수 μžˆλŠ” μœ„μΉ˜
int MAX;
bool is_ok(int y, int x) {
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < N; j++) {
            if (chess[i][j] == 2) {
                if (abs(i - y) == abs(j - x))
                    return false;
            }
        }
    }
    return true;
}
 
void backtracking(int depth, int B) {
    if (depth == cango.size()) {
        MAX = max(MAX, B);
        return;
    }
    if (is_ok(cango[depth].first, cango[depth].second)) { //λ‹€μŒμΉΈμ„ κ°ˆ μˆ˜ μžˆμœΌλ©΄
        chess[cango[depth].first][cango[depth].second]++;
        backtracking(depth + 1, B + 1);
        chess[cango[depth].first][cango[depth].second]--;
    }
    backtracking(depth + 1, B);
}
int main(void)
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cin >> N;
 
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < N; j++) {
            cin >> chess[i][j];
            if (chess[i][j])
                cango.push_back({ i,j });
        }
    }
    backtracking(00);
    cout << MAX << "\n";
    return 0;
}
 
 
cs

λ¬Όλ‘  μ˜ˆμ œκ°€ λ§žμ•„μ„œ μ œμΆœν–ˆλŠ”λ° κ·ΈλŒ€λ‘œ μ‹œκ°„μ΄ˆκ³Ό. 이 방법이 μ™Έμ—” λ”±νžˆ λ– μ˜€λ₯΄λŠ” 방법이 μ—†μ—ˆλ‹€. 1μ‹œκ°„ λ„˜κ²Œ κ³ λ―Όν–ˆμ§€λ§Œ κ²°κ΅­ μš±μ œλ‹˜μ˜ λΈ”λ‘œκ·Έλ₯Ό μ°Έκ³ ν–ˆλ‹€.

체슀의 νŠΉμ„±μ„ μ΄μš©ν•΄μ„œ 검은색 μΉΈκ³Ό 흰색 칸을 λ‚˜λˆ μ„œ μƒκ°ν•˜λ©΄ μ‹œκ°„μ„ 단좕할 수 μžˆλ‹€. μ™œλƒ κ²€μ • μΉΈκ³Ό 흰 칸은 μ„œλ‘œ μ ˆλŒ€ 같은 λŒ€κ°μ„ μ— μžˆμ„ 수 μ—†λ‹€.

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
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstdio>
#include <string.h>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <climits>
#include <algorithm>
#include <tuple>
#include <cmath>
using namespace std;
typedef long long ll;
int N;
const int MAX_N = 10 + 3;
int chess[MAX_N][MAX_N];
vector<pair<intint>> cango[2];
stack<pair<intint>> bishop[2];
int MAX[2];
 
bool is_ok(int y, int x, int depth, int black_white) {
    stack<pair<intint>> S(bishop[black_white]);
    while (!S.empty()) {
        int temp_y = S.top().first;
        int temp_x = S.top().second;
        S.pop();
        if (abs(y - temp_y) == abs(x - temp_x))
            return false;
    }
    return true;
}
//void show_chess() {
//    for (int i = 0; i < N; i++) {
//        for (int j = 0; j < N; j++) {
//            cout << chess[i][j] << " ";
//        }
//        cout << "\n";
//    }
//}
 
void backtracking(int depth, int B, int black_white) {
    if (depth == cango[black_white].size()) {
        MAX[black_white] = max(MAX[black_white], B);
        return;
    }
    if (is_ok(cango[black_white][depth].first, cango[black_white][depth].second, depth, black_white)) { //λ‹€μŒμΉΈμ„ κ°ˆ μˆ˜ μžˆμœΌλ©΄
        chess[cango[black_white][depth].first][cango[black_white][depth].second]++;
        bishop[black_white].push({cango[black_white][depth].first, cango[black_white][depth].second});
        backtracking(depth + 1, B + 1, black_white);
        bishop[black_white].pop();
        chess[cango[black_white][depth].first][cango[black_white][depth].second]--;
    }
    backtracking(depth + 1, B, black_white);
}
int main(void)
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cin >> N;
 
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < N; j++) {
            cin >> chess[i][j];
            if (chess[i][j]) {
                if (i % 2 == 0 && j % 2 == 0)
                    cango[0].push_back({ i,j });
                else if (i % 2 == 1 && j % 2 == 1)
                    cango[0].push_back({ i,j });
                else cango[1].push_back({ i,j });
            }
        }
    }
    backtracking(000);
    backtracking(001);
    cout << MAX[0+ MAX[1<< "\n";
    return 0;
}
 
 
cs

κ·Έλ ‡κ²Œ κΈ°μ‘΄ μ½”λ“œμ—μ„œ κΈ‰ν•˜κ²Œ μ½”λ“œλ₯Ό λ°”κΏ” μ œμΆœν•΄μ„œ ACλ₯Ό λ°›μ•˜λ‹€.

처음 μ½”λ“œμ˜ μ‹œκ°„λ³΅μž‘λ„λŠ” 2 * N * N (2λŠ” λ°±νŠΈλž˜ν‚Ήμ—μ„œ λΉ„μˆμ„ 놓냐 μ•ˆλ†“λƒ)

반반 λ‚˜λˆ μ„œ ν•œ μ½”λ“œμ˜ μ‹œκ°„λ³΅μž‘λ„λŠ” 2* N/2 * N/2 둜 훨씬 더 μ€„μ–΄λ“€μ—ˆλ‹€.

체슀판의 νŠΉμ„±μ„ ν™œμš©ν•˜λŠ” μ„ΌμŠ€κ°€ ν•„μš”ν–ˆλ˜ λ¬Έμ œλ‹€.

728x90

'λ°±μ€€ > Gold' μΉ΄ν…Œκ³ λ¦¬μ˜ λ‹€λ₯Έ κΈ€

[BOJ] 1707 : 이뢄 κ·Έλž˜ν”„  (0) 2022.01.21
[BOJ] 1579 : μ•±  (0) 2022.01.20
[BOJ] 10942 : νŒ°λ¦°λ“œλ‘¬?  (0) 2022.01.20
[BOJ] 2629 : μ–‘νŒ”μ €μšΈ  (0) 2022.01.19
[BOJ] 2661: 쒋은 μˆ˜μ—΄  (0) 2022.01.19