#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <stdio.h>
#include <vector>
#include <algorithm>
using namespace std;
vector<vector<int>> board;
int n, m, h;
int answer = 1000;
//범위 안에 있는지
bool inRange(int row, int col) {
if (1 <= row && row < h + 1 && 1 <= col && col < 2 * n)
return true;
return false;
}
bool isAnswer() {
int check = 0;
for (int j = 1; j < 2 * n; j = j + 2) {
//사다리 한 줄씩 확인
int row = 1; //처음 row부터
int col = j;
while (row <= h) {
//왼쪽 가로선 확인
if (inRange(row, col -1) && board[row][col - 1] == 1) {
col = col - 2; //있으면 이동
}
//오른쪽 가로선 확인
else if (inRange(row, col + 1) && board[row][col + 1] == 1) {
col = col + 2; //있으면 이동
}
row++; //밑으로도 한 칸
}
if (j == col) {
check++; //처음 시작한 곳과 끝난 곳이 같으면
}
}
if (check == n) //모두 처음 시작한 곳과 끝난 곳이 같으면
return true; //정답
else
return false;
}
//row, col에 사다리 가로 줄 놓을 수 있는가
bool isPossiblePut(int row, int col) {
//내가 놓으려는 곳이 가로줄 첫 열이라면 연속 확인 필요 없음. 그냥 놓으려는 곳에 가로줄 없는지만 체크
if (!inRange(row, col - 2) && board[row][col] == 0)
return true;
//이전 연속인가 확인
if (inRange(row, col - 2) && board[row][col - 2] == 0 && board[row][col] == 0)
return true;
return false;
}
//cnt번째 할거야. row, col에 놓을거야
void recursive(int cnt, int row, int col) {
if (isAnswer()) {
//놓은건 cnt-1개이므로
answer = min(answer, cnt - 1);
return; //최소값이니까 더 볼 필요 없음
}
if (cnt == 4) {
return;
}
bool isFirst = true;
for (int i = row; i < h + 1; i++) {
for (int j = 2; j < 2 * n; j = j+2) {
if (isFirst) {
isFirst = false;
j = col - 2;
continue;
}
//i,j에 놓을 수 있다면
if (isPossiblePut(i,j)) {
board[i][j] = 1; //놓기
recursive(cnt + 1, i, j + 2); //재귀
board[i][j] = 0; //원래대로
}
}
}
}
int main() {
scanf("%d %d %d", &n, &m, &h);
board = vector<vector<int>>(h + 1, vector<int>(2 * n, 0));
//board의 홀수 열은 사다리 세로 줄 있는 곳 (모두 1)
//board의 짝수 열은 사다리 가로 줄 놓을 수 있는 곳
//가로줄
for (int i = 1; i <= m; i++) {
int a, b;
scanf("%d %d", &a, &b);
board[a][2 * b] = 1;
}
//세로줄
for (int i = 1; i < h + 1; i++) {
for (int j = 1; j < 2 * n; j = j + 2) {
board[i][j] = 1;
}
}
//////////////
recursive(1, 1, 2);
if (answer == 1000) //답 없다면
printf("-1\n");
else
printf("%d\n", answer);
return 0;
}
완전탐색
사다리를 어떻게 표현할지 고민한 문제... 홀수열은 세로줄, 짝수열은 가로줄을 놓기로 하고 진행함
https://www.acmicpc.net/problem/15684
15684번: 사다리 조작
사다리 게임은 N개의 세로선과 M개의 가로선으로 이루어져 있다. 인접한 세로선 사이에는 가로선을 놓을 수 있는데, 각각의 세로선마다 가로선을 놓을 수 있는 위치의 개수는 H이고, 모든 세로선
www.acmicpc.net
'Baekjoon' 카테고리의 다른 글
[#15686] 치킨 배달 (0) | 2020.10.16 |
---|---|
[#14503] 로봇 청소기 (0) | 2020.10.13 |
[#16236] 아기상어 (0) | 2020.10.12 |
[#14502] 연구소 (0) | 2020.10.12 |
[#14499] 주사위 굴리기 (0) | 2020.10.11 |