길민호(ethan.mino)
코딩수첩
길민호(ethan.mino)
전체 방문자
오늘
어제
  • 분류 전체보기 (215)
    • Computer Science (0)
    • Web (6)
      • CSS (0)
      • HTML (0)
    • Node.js (0)
    • Javascript (2)
    • Java (46)
      • Spring (27)
      • Jsp (0)
    • C\C++ (2)
    • Programming (0)
    • AI (0)
    • Database (7)
    • Git (5)
    • Algorithm (119)
      • Stack (0)
      • Queue (0)
      • Linked List (0)
      • Sort (0)
      • Simulation (27)
      • Recursion (0)
      • Backtracking (4)
      • Two Pointer (3)
      • Dynamic Programming (19)
      • Greedy (10)
      • Graph (3)
      • Dijkstra (1)
      • BFS\DFS (8)
      • Floyd (1)
      • MST (4)
      • Tree (4)
      • Binary Search (8)
      • Binary Search Tree (4)
    • IntelliJ (4)
    • Vscode (0)
    • Operating System (0)
    • 후기 (3)
    • 성장일지 (13)
    • 스터디 (7)
    • 설치 (1)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • ㅡ

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
길민호(ethan.mino)

코딩수첩

[백준 1799번] 비숍 (C/C++)
Algorithm

[백준 1799번] 비숍 (C/C++)

2022. 3. 12. 00:40

 

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

 

1799번: 비숍

첫째 줄에 체스판의 크기가 주어진다. 체스판의 크기는 10이하의 자연수이다. 둘째 줄부터 아래의 예와 같이 체스판의 각 칸에 비숍을 놓을 수 있는지 없는지에 대한 정보가 체스판 한 줄 단위로

www.acmicpc.net


비숍은 N-Queen 문제와 유사합니다.

비숍의 움직임

비숍은 대각선으로 공격할 수 있기 때문에 배치된 비숍의 대각선으로는 다른 비숍을 배치할 수 없습니다.

따라서 백트래킹 기법을 이용하여 각 대각선마다 하나의 비숍을 배치시키면서 가능한 경우의 수를 모두 수행해봄으로써 체스판 위에 배치할 수 있는 비숍의 개수를 계산할 수 있습니다. (저는 우상향 대각선을 이용하였습니다.)

 

n이 5일 때, 대각선의 개수는 9개입니다. 즉, 2n - 1개입니다.

백트래킹의 끝단에서는 마지막 대각선에 비숍을 배치하므로, 대각선의 개수를 이용하여 재귀를 탈출 할 수 있습니다. 

1 1 0 1 1
0 1 0 0 0
1 0 1 0 1
1 0 0 0 0
1 0 1 1 1

 

n이 5일 때, 각 대각선의 칸의 개수는 아래와 같습니다. 따라서 th번째 대각선의 칸의 개수는 n - |th - (n - 1)|으로 계산할 수 있습니다.

th = 0 -> 1개
th = 1 -> 2개
th = 2 -> 3개
th = 3 -> 4개
th = 4 -> 5개
th = 5 -> 4개
th = 6 -> 3개
th = 7 -> 2개
th = 8 -> 1개
th = 9 -> 0개

 

각 대각선에 위치한 각 칸의 좌표는 아래와 같이 계산할 수 있습니다.

int x = (n - 1 <= th) ? n - 1 - j : th - j; // th번째 대각선의 j번째 위치의 x좌표
int y = (n - 1 <= th) ? th - (n - 1) + j : j;  // th번째 대각선의 j번째 위치의 y좌표

 

아래는 전체 코드입니다. 

#include <bits/stdc++.h>
using namespace std;

#define x first
#define y second

int n;  // 체스판의 크기
int board[10][10];  // 체스판
bool isused1[20];   // 우상향 대각선에 대한 상태 배열
bool isused2[20];   // 좌상향 대각선에 대한 상태 배열

int ans = 0;
void bishop(int th, int size){  // th는 우상향 대각선의 index, size는 이전에 선택한 비숍의 개수
    if(th >= 2 * n - 1){    
        ans = max(ans , size); 
    }else{
        bool flag = false;  // th번째 대각선에서 비숍을 놓았는지를 나타내는 flag

        for(int j = 0; j < n - abs(th - (n- 1)); j++){   
            int x = (n - 1 <= th) ? n - 1 - j : th - j;
            int y = (n - 1 <= th) ? th - (n - 1) + j : j;  

            // 비숍을 놓을 수 있으면서, 우상향 대각선과 좌상향 대각선에 비숍이 없는 경우
            if(board[x][y] == 1 && !isused1[th] && !isused2[n - 1 + (x - y)]){  
                flag = true;    
                isused1[th] = true; // 비숍을 놓는 위치에 해당하는 우상향 대각선에 true를 표시
                isused2[n - 1 + (x - y)] = true;    // 좌상향 대각선에 true를 표시
                bishop(th + 1, size + 1); 
                isused1[th] = false;    // 우상향 대각선을 false로 복구
                isused2[n - 1 + (x - y)] = false; // 좌상향 대각선을 false로 복구
            }
        }
        // th 번째 대객선에서 비숍을 놓지 않았다면, size를 늘리지 않고, th + 1번째 비숍을 선택
        if(!flag) bishop(th + 1, size); 
    }

}

int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);
    cin >> n;

    for(int i =0 ; i < n; i++)  // 체스판 입력 받음
        for(int j = 0; j < n; j++)
            cin >> board[i][j];

    bishop(0, 0);
    cout << ans;
}

아래는 문제 해결에 사용된 테스트케이스입니다.

5
1 1 0 1 1
0 1 0 0 0
1 0 1 0 1
1 0 0 0 0
1 0 1 1 0

3
0 0 0
0 0 0
0 0 0

3
0 0 0
0 0 0
0 0 1

3
0 0 1
0 1 0
0 0 1

10
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1

'Algorithm' 카테고리의 다른 글

[백준 2805번] 나무 자르기 (C/C++)  (0) 2022.03.14
[백준 18111번] 마인크래프트 (C/C++)  (0) 2022.03.12
[백준 18809번] Gaaaaaaaaaarden (C/C++)  (0) 2022.03.11
[백준 1941번] 소문난 칠공주 (C/C++)  (0) 2022.03.11
[백준 15655번] N과 M (9) (C/C++)  (0) 2022.03.09
    'Algorithm' 카테고리의 다른 글
    • [백준 2805번] 나무 자르기 (C/C++)
    • [백준 18111번] 마인크래프트 (C/C++)
    • [백준 18809번] Gaaaaaaaaaarden (C/C++)
    • [백준 1941번] 소문난 칠공주 (C/C++)
    길민호(ethan.mino)
    길민호(ethan.mino)
    💻 호기심 많은 서버 개발자 길민호입니다.

    티스토리툴바