Skip to content

Conversation

@froglike6
Copy link
Collaborator

@froglike6 froglike6 commented Apr 6, 2025

πŸ”— 문제 링크

N-Queen

βœ”οΈ μ†Œμš”λœ μ‹œκ°„

μ•½ 40λΆ„

✨ μˆ˜λ„ μ½”λ“œ

μ„œλ‘œ κ³΅κ²©ν•˜μ§€ μ•ŠλŠ” N개의 퀸을 NΓ—N 체슀판 μœ„μ— 놓을 수 μžˆλŠ” λͺ¨λ“  경우의 수λ₯Ό κ΅¬ν•˜λŠ” λ¬Έμ œμž…λ‹ˆλ‹€.

퀸은 같은 ν–‰, 같은 μ—΄, 같은 λŒ€κ°μ„ μ— μžˆλŠ” 말을 곡격할 수 μžˆμœΌλ―€λ‘œ, λ‹€μŒ μ œμ•½μ„ λ§Œμ‘±ν•˜λŠ”μ§€ ν™•μΈν•˜λ©° νƒμƒ‰ν•©λ‹ˆλ‹€.

μˆ˜λ„μ½”λ“œ

1. μž…λ ₯으둜 n(체슀판 크기)λ₯Ό λ°›λŠ”λ‹€.

2. λ°±νŠΈλž˜ν‚Ή ν•¨μˆ˜ dfs(row, cols, diag1, diag2)λ₯Ό μ •μ˜ν•œλ‹€.
   - row: ν˜„μž¬ 탐색 쀑인 ν–‰ 번호
   - cols: 이미 퀸이 놓인 μ—΄ 정보 (λΉ„νŠΈλ§ˆμŠ€ν¬)
   - diag1: "/" λ°©ν–₯ λŒ€κ°μ„  정보 (μ™Όμͺ½ μœ„ β†’ 였λ₯Έμͺ½ μ•„λž˜)
   - diag2: "\" λ°©ν–₯ λŒ€κ°μ„  정보 (였λ₯Έμͺ½ μœ„ β†’ μ™Όμͺ½ μ•„λž˜)

3. dfsμ—μ„œ λ‹€μŒμ„ μˆ˜ν–‰ν•œλ‹€.
   - rowκ°€ n이면 퀸을 λͺ¨λ‘ λ°°μΉ˜ν•œ κ²½μš°μ΄λ―€λ‘œ ν•΄ 개수λ₯Ό +1 ν•œλ‹€.
   - κ°€λŠ₯ν•œ μœ„μΉ˜λ₯Ό λΉ„νŠΈ μ—°μ‚°μœΌλ‘œ κ΅¬ν•œλ‹€.
     available = ~(cols | diag1 | diag2) & ((1 << n) - 1)
   - κ°€λŠ₯ν•œ λͺ¨λ“  μœ„μΉ˜μ— λŒ€ν•΄:
     - ν•˜λ‚˜μ˜ μœ„μΉ˜ pλ₯Ό 선택 (κ°€μž₯ 였λ₯Έμͺ½ λΉ„νŠΈ)
     - ν•΄λ‹Ή μœ„μΉ˜λ₯Ό λ§ˆμŠ€ν¬μ—μ„œ 제거
     - μž¬κ·€ 호좜: λ‹€μŒ ν–‰μœΌλ‘œ μ΄λ™ν•˜κ³ , cols, diag1, diag2λ₯Ό κ°±μ‹ ν•˜μ—¬ μ „λ‹¬ν•œλ‹€.

4. 결과값을 좜λ ₯ν•œλ‹€.

ezgif-4ec8fb9c3774e9

μ €λŠ” λΉ„νŠΈλ§ˆμŠ€ν¬λ₯Ό μ΄μš©ν•œ λ°±νŠΈλž˜ν‚Ή λ°©μ‹μœΌλ‘œ ν•΄κ²°ν–ˆμŠ΅λ‹ˆλ‹€.
μ˜ˆμ „μ— μ–΄λŠ μ–΄λ €μš΄ 문제(μ•„λ§ˆλ„ 루비 문제)μ—μ„œ 봀던 기얡이 λ‚˜μ„œ μ‚¬μš©ν•΄λ³΄μ•˜μŠ΅λ‹ˆλ‹€.
이 방법은 μ—΄/λŒ€κ°μ„  μ œμ•½ 쑰건을 λΉ„νŠΈ μ—°μ‚°μœΌλ‘œ λΉ λ₯΄κ²Œ 검사할 수 μžˆμ–΄ 맀우 νš¨μœ¨μ μž…λ‹ˆλ‹€.

λΉ„νŠΈλ§ˆμŠ€ν¬

λΉ„νŠΈλ§ˆμŠ€ν¬λŠ” μ •μˆ˜μ˜ μ΄μ§„μˆ˜ ν‘œν˜„μ„ ν™œμš©ν•˜μ—¬ μ—¬λŸ¬ 개의 μƒνƒœλ₯Ό ν•˜λ‚˜μ˜ 숫자둜 ν‘œν˜„ν•˜λŠ” κΈ°λ²•μž…λ‹ˆλ‹€.
각 λΉ„νŠΈλŠ” νŠΉμ • 쑰건의 μΆ©μ‘± μ—¬λΆ€λ₯Ό μ˜λ―Έν•˜λ©°, 1이면 μ°Έ(True), 0이면 κ±°μ§“(False)을 λ‚˜νƒ€λƒ…λ‹ˆλ‹€.

μ˜ˆμ‹œ

체슀판이 n = 4일 λ•Œ,
숫자 0b1010 (μ΄μ§„μˆ˜)은 λ‹€μŒκ³Ό 같은 μƒνƒœλ₯Ό λœ»ν•©λ‹ˆλ‹€:

  • 0번 μ—΄: μ—†μŒ (0)
  • 1번 μ—΄: 있음 (1)
  • 2번 μ—΄: μ—†μŒ (0)
  • 3번 μ—΄: 있음 (1)

즉, 퀸이 1번과 3번 열에 μžˆλ‹€λŠ” λœ»μž…λ‹ˆλ‹€.


μ½”λ“œ μ„€λͺ…

  • cols: νŠΉμ • 열에 퀸이 이미 λ°°μΉ˜λ˜μ—ˆλŠ”μ§€ μ—¬λΆ€
  • diag1: β†˜ λ°©ν–₯ λŒ€κ°μ„  (row + col이 같은 μœ„μΉ˜)
  • diag2: ↙ λ°©ν–₯ λŒ€κ°μ„  (row - col이 같은 μœ„μΉ˜)

λΉ„νŠΈ 연산을 톡해 좩돌 μ—¬λΆ€λ₯Ό O(1)둜 νŒλ‹¨ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

available = ~(cols | diag1 | diag2) & ((1 << n) - 1)

이 μ½”λ“œλŠ” "ν˜„μž¬ ν–‰μ—μ„œ 퀸을 놓을 수 μžˆλŠ” μœ„μΉ˜"λ₯Ό κ³„μ‚°ν•©λ‹ˆλ‹€.
ν•œ 쀄씩 μ‰½κ²Œ μ„€λͺ…해보면:

  1. cols | diag1 | diag2

    μ§€κΈˆκΉŒμ§€ 퀸이 놓인 μ—΄, β†˜ λ°©ν–₯ λŒ€κ°μ„ , ↙ λ°©ν–₯ λŒ€κ°μ„  정보λ₯Ό λͺ¨λ‘ ν•©μΉ©λ‹ˆλ‹€.

    • | 연산은 "λ˜λŠ”"μ΄λ―€λ‘œ, μ–΄λŠ ν•œ 곳이라도 퀸이 있으면 1이 λ©λ‹ˆλ‹€.
  2. ~(cols | diag1 | diag2)

    μœ„μ—μ„œ 1이 된 λΆ€λΆ„(퀸이 μžˆκ±°λ‚˜ κ³΅κ²©λ°›λŠ” 자리)을 λ°˜μ „μ‹œμΌœ
    β†’ 퀸을 놓을 수 μžˆλŠ” 자리만 1둜 λ§Œλ“­λ‹ˆλ‹€.

  3. & ((1 << n) - 1)

    예: n = 4라면 1 << 4 = 16 = 0b10000
    ((1 << n) - 1) β†’ 0b1111 (ν•˜μœ„ nλΉ„νŠΈλ§Œ 1)
    이것을 & μ—°μ‚°ν•΄μ„œ n x n 체슀판 μ΄μ™Έμ˜ μƒμœ„ λΉ„νŠΈλ₯Ό μ œκ±°ν•©λ‹ˆλ‹€.

이 κ³„μ‚°μ˜ 결과인 available은
ν˜„μž¬ ν–‰μ—μ„œ 퀸을 놓을 수 μžˆλŠ” 열을 1둜 ν‘œμ‹œν•œ λΉ„νŠΈλ§ˆμŠ€ν¬μž…λ‹ˆλ‹€.


λ‹€μŒ μ½”λ“œ

position = available & -available
  • ν˜„μž¬ κ°€λŠ₯ν•œ 자리 μ€‘μ—μ„œ κ°€μž₯ 였λ₯Έμͺ½μ— μžˆλŠ” 1λΉ„νŠΈ ν•˜λ‚˜λ§Œ μΆ”μΆœν•©λ‹ˆλ‹€.
  • 예: available = 0b10100 β†’ position = 0b00100
available &= available - 1
  • 방금 μ„ νƒν•œ 자리(position)λ₯Ό availableμ—μ„œ μ œκ±°ν•©λ‹ˆλ‹€.
  • λ‹€μŒ λ°˜λ³΅μ—μ„œλŠ” λ‚˜λ¨Έμ§€ κ°€λŠ₯ν•œ μžλ¦¬λ“€λ§Œ νƒμƒ‰ν•˜κ²Œ λ©λ‹ˆλ‹€.

λ°±νŠΈλž˜ν‚Ή

λ°±νŠΈλž˜ν‚Ήμ€ κ°€λŠ₯ν•œ ν•΄λ₯Ό μ°ΎκΈ° μœ„ν•΄ λͺ¨λ“  후보λ₯Ό νƒμƒ‰ν•˜λ˜, μœ νš¨ν•˜μ§€ μ•Šμ€ 경우 더 κΉŠμ€ 탐색을 ν•˜μ§€ μ•Šκ³  μ¦‰μ‹œ λ˜λŒμ•„κ°€λŠ” 탐색 κΈ°λ²•μž…λ‹ˆλ‹€.

이 λ¬Έμ œμ—μ„œλŠ” λ‹€μŒκ³Ό 같은 μ‘°κ±΄μ—μ„œ λ°±νŠΈλž˜ν‚Ήμ΄ μ μš©λ©λ‹ˆλ‹€:

  • ν˜„μž¬ μœ„μΉ˜μ— 퀸을 λ†“μ•˜μ„ λ•Œ, μ—΄/λŒ€κ°μ„  쀑 ν•˜λ‚˜λΌλ„ 이미 μ‚¬μš© 쀑이면 μ¦‰μ‹œ κ°€μ§€μΉ˜κΈ°
  • κ·Έλ ‡μ§€ μ•ŠμœΌλ©΄ μž¬κ·€μ μœΌλ‘œ λ‹€μŒ 행에 λŒ€ν•΄ 반볡
  • 퀸을 N개 μ „λΆ€ λ°°μΉ˜ν•˜λ©΄ ν•΄μ˜ 수λ₯Ό μ¦κ°€μ‹œν‚΄

πŸ“š μƒˆλ‘­κ²Œ μ•Œκ²Œλœ λ‚΄μš©

  • λΉ„νŠΈ 연산을 ν™œμš©ν•˜λ©΄ μ—΄, λŒ€κ°μ„  좩돌 μ—¬λΆ€λ₯Ό 맀우 λΉ λ₯΄κ²Œ νŒλ‹¨ν•  수 μžˆμ–΄ μ„±λŠ₯이 크게 ν–₯상됨
  • x & -xλ₯Ό μ΄μš©ν•΄ κ°€μž₯ 였λ₯Έμͺ½ 1λΉ„νŠΈλ₯Ό λΉ λ₯΄κ²Œ μΆ”μΆœν•  수 있음 (λŒ€ν‘œμ μΈ λΉ„νŠΈλ§ˆμŠ€ν¬ 트릭)
  • λ°±νŠΈλž˜ν‚Ήμ— λΉ„νŠΈλ§ˆμŠ€ν¬λ₯Ό κ²°ν•©ν•˜λ©΄ νš¨μœ¨μ„±κ³Ό λ‹¨μˆœμ„±μ„ λ™μ‹œμ— 얻을 수 있음
  • OEIS A000170 μˆ˜μ—΄μ„ 톡해 N-Queens 문제의 ν•΄ 개수λ₯Ό 사전에 μ°Έκ³ ν•  수 있음

μ°Έκ³ : OEIS A000170

Copy link
Collaborator

@hadongun hadongun left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

였.. λΉ„νŠΈ 연산을 톡해 좩돌 μ—¬λΆ€λ₯Ό νŒλ‹¨ ν•  수 μžˆκ΅°μš”..!
μ €λŠ” for문을 톡해 row행에 퀸을 놓고 같은 열에 퀸이 μžˆλŠ”μ§€(col[row]), λŒ€κ°μ„  λ°©ν–₯에 퀸이 μžˆλŠ”μ§€ ν™•μΈν•˜λŠ” 방법을 생각해봀어μš₯

        if col[i] == col[row] or abs(col[row] - col[i]) == row - i:

Copy link
Collaborator

@caucsejunseo caucsejunseo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

μ˜μƒκ³Ό μ½”λ“œ ν•œμ€„ ν•œμ€„ μ„€λͺ…을 λ‹¬μ•„μ£Όμ…”μ„œ μ΄ν•΄ν•˜κΈ° λ„ˆλ¬΄ μ’‹μ•˜μŠ΅λ‹ˆλ‹€!

처음 문제 봀을 λ•Œ 이차원 배열을 μƒκ°ν–ˆλŠ”λ° λΉ„νŠΈ μ—°μ‚°μœΌλ‘œ ν•΄κ²°ν•˜μ‹  점이 ν₯λ―Έλ‘œμ› μŠ΅λ‹ˆλ‹€

λ°±νŠΈλ ˆν‚Ήμ— λŒ€ν•΄μ„œλ„ μƒˆλ‘œ μ ‘ν•˜κ²Œ λ˜μ„œ μœ μ΅ν–ˆλ˜ κ±° κ°™μ•„μš”

Copy link
Contributor

@dohyeondol1 dohyeondol1 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

μ™€μš°...μ €λŠ” 이거 μˆ˜λ„ μ½”λ“œ μ—†μ—ˆμœΌλ©΄ λͺ» 읽을뻔 ν–ˆλ„€μš”...
λ°±νŠΈλž˜ν‚Ήμ— λŒ€ν•΄μ„œ 곡뢀도 κ°™μ΄ν•˜λŠ”κ²Έ 문제λ₯Ό 풀어보렀고 ν–ˆλŠ”λ°,
접근은 μ‰¬μ› λŠ”λ° κ΅¬ν˜„ λŠ₯λ ₯이 μ•„μ‰¬μ›Œμ„œ,, 문제λ₯Ό 맞좜 λ•Œ κΉŒμ§€ μ‹œκ°„μ΄ 였래 κ±Έλ ΈμŠ΅λ‹ˆλ‹€..

μ €λŠ” λΉ„νŠΈλ§ˆμŠ€ν‚Ήμ— λŒ€ν•œ κ°œλ…μ„ λͺ°λΌμ„œ κ·Έλƒ₯ λ°±νŠΈλž˜ν‚ΉμœΌλ‘œλ§Œ ν’€μ—ˆμ”λ‹ˆλ‹·.
인덱슀λ₯Ό ν–‰μœΌλ‘œ, 값을 μ—΄λ‘œ μ„€μ •ν•œ 배열을 μ‚¬μš©ν–ˆμŠ΅λ‹ˆλ‹€.
μ²˜μŒμ— κ·Έλƒ₯ ν–‰ μ—΄ λ‘˜ λ‹€ 인덱슀둜 써보렀닀가 값을 λ„£μ„κ²Œ μ—†λ”λΌκ΅¬μš”.

같은 열에 μœ„μΉ˜ν•˜λŠ”μ§€, 같은 λŒ€κ°μ„ μ— μœ„μΉ˜ν•˜λŠ”μ§€ κ²€μ‚¬ν•΄μ„œ λΆ€λ”ͺνžˆμ§€ μ•Šκ²Œ 쑰건문을 μ§°μŠ΅λ‹ˆλ‹€.

λ°±νŠΈλž˜ν‚Ή μžμ²΄λ„ 였늘 찾아보고 배우기 μ‹œμž‘ν•œκ±°λΌ 슀슀둜 ν’€μ–΄λ‚΄μ—λŠ” λ°μ—λ§Œ 2μ‹œκ°„μ€ μ“΄ 것 κ°™μŠ΅λ‹ˆλ‹€.. promising을 κ²€μ‚¬ν•˜λŠ” λΆ€λΆ„μ—μ„œ κ½€λ‚˜ μ• λ₯Ό λ¨Ήμ—ˆλ„€μš”..

C++ μ½”λ“œ
#include <iostream>
using namespace std;

int N;
int result = 0;
int column[15];

bool isPromising(int currentRow) {
    for(int prevRow = 0; prevRow < currentRow; prevRow++) {
        if(column[prevRow] == column[currentRow] || abs(column[currentRow] - column[prevRow]) == currentRow - prevRow) {
            return false;
        }
    }
    return true;
}

void NQueens(int row) {
    if(row == N) {
        result++;
        return;
    }
    
    for(int i = 0; i < N; i++) {
        column[row] = i;
        if(isPromising(row)) {
            NQueens(row + 1);
        }
    }
}

int main() {
    cin >> N;
    NQueens(0);
    cout << result << endl;
    return 0;
}

λ²ˆμ™Έλ‘œ 이런 ν•˜λ“œμ½”λ”©λ„ μ •λ‹΅μœΌλ‘œ μ³μ£Όλ”κ΅°μš”...ν—ˆν—ˆ

μž…λ ₯λŒ€λ‘œ μ •ν•΄μ§„ 정닡을 좜λ ₯ν•˜λŠ” μ½”λ“œ
#include <iostream>
using namespace std;

int main() {
    int N;
    cin >> N;

    if (N == 1) cout << 1 << endl;
    else if (N == 2) cout << 0 << endl;
    else if (N == 3) cout << 0 << endl;
    else if (N == 4) cout << 2 << endl;
    else if (N == 5) cout << 10 << endl;
    else if (N == 6) cout << 4 << endl;
    else if (N == 7) cout << 40 << endl;
    else if (N == 8) cout << 92 << endl;
    else if (N == 9) cout << 352 << endl;
    else if (N == 10) cout << 724 << endl;
    else if (N == 11) cout << 2680 << endl;
    else if (N == 12) cout << 14200 << endl;
    else if (N == 13) cout << 73712 << endl;
    else if (N == 14) cout << 365596 << endl;

    return 0;
}

λΉ„νŠΈλ§ˆμŠ€ν‚Ή κ°œλ…μ΄ ν₯미둜운데 μ΄κ²ƒκΉŒμ§€ κ³΅λΆ€ν•˜κΈ°μ—λŠ” 무리가 μžˆμ–΄λ³΄μ΄λ„€μš” ν—ˆν—£
주에 거의 μƒˆλ‘œμš΄ κ°œλ…μ„ 2,3κ°œμ”© κ³΅λΆ€ν•˜λŠ” 것 κ°™μ•„μš”..

μ‘°λ§Œκ°„ 볡슡 μ°¨μ›μ—μ„œ ν•œλ°”ν€΄ μ‹Ή λŒλ €μ•Όκ² μŠ΅λ‹ˆλ‹€..

@froglike6 froglike6 merged commit 2ef6fbf into main Apr 11, 2025
1 check passed
@dohyeondol1 dohyeondol1 deleted the 6-froglike6 branch May 10, 2025 18:54
@froglike6 froglike6 mentioned this pull request Jun 26, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants