반응형
문제 : https://www.acmicpc.net/problem/15684
서론
브루트포스 문제. 재귀를 이용하여 완전탐색했다.
풀이
의사코드는
main(){
사다리 입력받음
사다리설치()
결과 출력
}
사다리설치(좌표, 추가한 사다리 개수, 사다리 설치){
if(좌표가 지도의 끝){
사다리를 탄다();
if(사다리를 타보니 조건이 맞다) 결과 갱신
}
다음칸으로 이동할 좌표 생성
if(다음칸 사다리가 설치되어 있지 않다){
다음칸 사다리 설치
사다리설치(다음칸 좌표, 추가한 사다리 개수+1, true)
다음칸 사다리 회수
}
사다리설치(다음칸 좌표, 추가한 사다리 개수, false)
}
먼저 사다리를 지도에 입력해야하는데, 입력조건에 보면 가로선의 정보는 a, b로 나타내고 b번 세로선과 b+1번 세로선을 a 점선위치에 연결했다는 내용이 나온다. 이를 착안하여 사다리를 입력할 2차원배열을 만들고, 배열의 각 칸을 문제 그림의 가로선과 세로선이 만나는 점으로 한다. 그리고 사다리는 현재 칸이 1이면 현재 칸의 x와 x+1의 사이의 사다리를 나타낸다.
사다리를 설치하는 방법은 재귀를 이용한다.
https://hydroponicglass.tistory.com/30
위 링크의 문제와 같은 방식으로 재귀를 이용하여 2차원 배열의 칸들에 사다리를 1~3개까지 추가적으로 설치하는 모든 경우의 수를 탐색한다. 그리고 각각의 경우의 수에 대해 사다리를 태워서 조건에 맞는지 확인한다. 조건에 부합하면 결과값을 갱신한다.
사다리를 태우는 방법은
왼쪽 첫 열에서
y가 1에서 h에 도착할때까지 y값을 1 증가시키고 사다리가 현재칸에 있으면 x를 +1, 왼쪽칸에 있으면 x를 -1 하는것을 반복한다. 그리고 h에 도착했을때 x값이 현재 열의 값과 같으면 다음열로 넘어가서 위와 같은 방식으로 확인해주고 마지막열까지 확인되었다면 결과값을 갱신한다.
구현
// c++
#include <iostream>
#include <algorithm>
int map[31][11];
int result = -1;
int n, m, h;
bool cal() {
bool continueFlag = true;
for (int i = 1; i <= n; i++) {
int x = i;
int y = 1;
while (y <= h) {
if (x < n && map[y][x] == 1) x++;
else if (x > 1 && map[y][x - 1] == 1) x--;
y++;
}
if (x != i) {
continueFlag = false;
break;
}
}
return continueFlag;
}
void addLadder(int y, int x, int ladderCnt, bool set) {
if (ladderCnt > 3) return;
if (y >= h && x >= n) {
bool tf = cal();
if (tf == true) {
if (result == -1) result = ladderCnt;
else result = std::min(result, ladderCnt);
}
return;
}
else if (x == n) {
y++;
x = 1;
}
else {
x++;
}
if (x < n && map[y][x] == 0 && map[y][x + 1] == 0) {
map[y][x] = 1;
addLadder(y, x, ladderCnt + 1, true);
map[y][x] = 0;
}
addLadder(y, x, ladderCnt, false);
return;
}
int main() {
std::cin >> n >> m >> h;
for (int i = 0; i < m; i++) {
int a, b; // a는 가로선, b는 세로선
std::cin >> a >> b;
map[a][b] = 1; // 1이면 b와 b+1사이에 사다리 존재, -1이면 b와 b-1 사이에 사다리 존재
}
addLadder(1, 0, 0, false);
std::cout << result;
}
최근댓글