사다리 표현
배열로 : board[35][15]
가로선 연결여부 int로 (0: 연결 X, 1: 연결:O, 2: 새롭게 연결)
가로선의 유무 확인 : check()
if (board[i][j]) j++; // 오른쪽 이동
else if (board[i][j - 1] != 0) j--; // 왼쪽 이동
//else 아래로(열 그대로) 이동
가로선 두는 방법 : dfs
4% 시간초과
dfs로 사다리의 개수 0~3까지 살펴보는게 중복이므로 Level의 개수로 나눠서 돌리는 게 아닌 dfs 내에서 모든 level에서 check
void dfs(int L){
if (L == cnt) {
check();
return;
}
...
}
int main(){
...
for (int i=0; i<=3; i++){
cnt = i;
dfs(0);
}
...
}
void dfs(int L){
check();
if (L == 3) return;
...
}
int main(){
...
dfs(0);
...
}
dfs에서 사다리위치 선택할 때 앞에는 고려 안해도 됐음(이미 앞쪽에서 확인하므로 중복)
-> 시작 위치 가지고 다니게 하여 시간 초과 문제 해결
void dfs(int L){
...
for (auto coord: coords) {
if (board[coord.X][coord.Y]) continue;
board[coord.X][coord.Y] = 2;
dfs(L + 1);
board[coord.X][coord.Y] = 0;
}
...
}
void dfs(int L, int vi){
...
for (int i = vi; i<= coords.size(); i++) {
auto coord = coords[i];
if (board[coord.X][coord.Y]) continue;
board[coord.X][coord.Y] = 2;
dfs(L + 1, i+1);
board[coord.X][coord.Y] = 0;
}
...
}
12% 틀렸습니다
level을 0부터 시작하여 3까지 dfs는 깊이 탐색으로 쭉 들어가므로 답이 나왔다고 해서 그것이 최적(최솟값)이 아닐 수 있음
→ min 함수를 사용하여 최솟값을 가질 수 있게 해야함
- 옳은 코드
int ans = 0x7f7f7f7f; // Int의 근사 최댓값
void dfs(int L, int vi){
...
if (ans < L) return;
if (check()) {
ans = min(ans, L);
return;
}
...
}
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
#define X first
#define Y second
#define MAX 0x7f7f7f7f
int N, M, H;
int board[35][15];
vector<pair<int, int> > coords;
int ans = MAX;
bool isComplete;
bool check()
{
for (int n = 1; n <= N; n++)
{
int j = n;
for (int i = 1; i <= H; i++)
{
if (board[i][j] != 0)
j++;
else if (board[i][j - 1] != 0)
j--;
}
if (j != n)
return false;
}
return true;
}
void dfs(int L, int vi)
{
if (ans < L) return;
if (check())
{
ans = min(ans, L);
return;
}
if (L == 3) return;
for (int i = vi; i<coords.size(); i++){
auto coord = coords[i];
if (board[coord.X][coord.Y]) continue;
board[coord.X][coord.Y] = 2;
dfs(L + 1, i);
board[coord.X][coord.Y] = 0;
}
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cin >> N >> M >> H;
while (M--)
{
int a, b;
cin >> a >> b;
board[a][b] = 1;
}
for (int i = 1; i <= H; i++)
{
for (int j = 1; j < N; j++)
{
if (board[i][j] || board[i][j - 1] || board[i][j + 1])
continue;
coords.push_back(make_pair(i, j));
}
}
dfs(0, 0);
if (ans > 3) cout << "-1";
else cout << ans;
return 0;
}