dev_beomgeun
꾸준하게 차근차근
dev_beomgeun
전체 방문자
오늘
어제
  • 분류 전체보기 (170)
    • 전공 (0)
      • 운영체제 (0)
      • 알고리즘 (0)
      • 자료구조 (0)
      • 데이터베이스 (0)
      • 네트워크 (0)
    • 개발 공부 (32)
      • 웹 (6)
      • 리눅스 (4)
      • 머신러닝 (1)
      • 스프링 (17)
      • Git (2)
      • AWS (2)
    • 개발 도서, 강의 (3)
      • 스프링 입문을 위한 자바 객체지향의 원리와 이해 (0)
      • 모든 개발자를 위한 HTTP 웹 기본 지식(김영한.. (2)
      • 스프링 부트와 AWS로 혼자 구현하는 웹서비스 (1)
    • 문제 풀이 (118)
      • 백준 알고리즘 (72)
      • 프로그래머스 알고리즘, SQL (38)
      • Hackerrank SQL (8)
    • 프로젝트 기록 (4)
      • 캡스톤 종합설계 (4)
      • 반려하루 프로젝트 (0)
    • 활동 기록 (12)
      • 네이버 부스트캠프 (7)
      • 취준 & 코테 (4)
      • 소프트웨어 마에스트로 13기 (1)
    • 이것저것 (1)

블로그 메뉴

  • 홈
  • 깃허브
  • 링크드인
  • 방명록

공지사항

인기 글

태그

  • 프로그래머스
  • 서블릿
  • dp
  • AI Tech
  • 네이버 부스트캠프
  • 백준
  • 백준 DP
  • c++
  • 프로그래머스 SQL
  • 회고
  • Baekjoon
  • 스프링
  • Hackerrank
  • BFS
  • 일기
  • 부스트캠프
  • HackerRank mysql
  • 기록
  • 그래프탐색
  • 반성

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
dev_beomgeun

꾸준하게 차근차근

문제 풀이/백준 알고리즘

[baekjoon 17070] 파이프 옮기기 1 (DFS, 백트래킹) (C++)

2021. 4. 12. 19:17
728x90

www.acmicpc.net/problem/17070

 

17070번: 파이프 옮기기 1

유현이가 새 집으로 이사했다. 새 집의 크기는 N×N의 격자판으로 나타낼 수 있고, 1×1크기의 정사각형 칸으로 나누어져 있다. 각각의 칸은 (r, c)로 나타낼 수 있다. 여기서 r은 행의 번호, c는 열의

www.acmicpc.net

파이프를 옮겨서 주어진 사이즈의 끝점까지 옮길 수 있는 경우의 수를 찾는 문제이다.

신경 써줘야 할 점은

가로로 옮긴 다음엔 가로 OR 대각선

세로로 올긴 다음엔 세로 OR 대각선

대각선으로 옮긴 다음엔 가로 OR 세로 OR 대각선이 모두 가능하다.

또한 대각선으로 옮길 때에는 다음 나아갈 점뿐만 아니라 그 점의 위와 왼쪽 또한 벽이 없어야 한다.

 

이 조건만 잘 지켜주면서 모든 경우의 수를 탐색해주면 된다. (N이 최대 16이라 가능하다고 생각했다.)

 

처음엔 DFS+DP를 통해 미리 방문한 경로이면 dp값을 더해줘서 풀려고 했는데 이 방법을 사용하면 이미 방문한 길이 가로를 통해 방문했지만 나는 현재 세로인 상태에서 방문해버리면 틀리는 경우가 나오므로 방법을 바꿨다.

 

그냥 DFS로 탐색 + 백 트래킹 해주면서 모든 경우의 수를 찾았다. 

추가로, DFS의 파라미터에 어떤 방향으로 진행했는지 direction 변수를 넣어서 예외처리를 했다.

#include <iostream>

using namespace std;

int n, arr[17][17], xmove[3] = { 0, 1, 1 }, ymove[3] = { 1, 0, 1 };
int record[17][17], answer;

void DFS(int x, int y, int direction) {
	if (x == n - 1 && y == n - 1) {
		answer++;
		return;
	}

	for (int i = 0; i < 3; i++) {
		if (direction == 0 && i == 1)
			continue;
		else if (direction == 1 && i == 0)
			continue;
		else {
			int nx = x + xmove[i];
			int ny = y + ymove[i];

			if (nx >= 0 && nx < n && ny >= 0 && ny < n) {
				if (i == 0 || i == 1) {
					if (arr[nx][ny] == 0 && !record[nx][ny]) {
						record[nx][ny] = true;
						DFS(nx, ny, i);
						record[nx][ny] = false;
					}
				}
				else {
					if (arr[nx][ny] == 0 && arr[nx-1][ny] == 0 && arr[nx][ny-1] == 0 && !record[nx][ny]) {
						record[nx][ny] = true;
						DFS(nx, ny, i);
						record[nx][ny] = false;
					}
				}
			}
		}
	}
}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cin >> n;
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < n; j++) {
			cin >> arr[i][j];
		}
	}

	DFS(0, 1, 0);

	cout << answer;
}

direction은 0은 가로, 1은 세로, 2는 대각선이므로

만약 0인데 1이면 (가로-세로)의 경우이므로 continue

마찬가지로 1인데 0이면(세로-가로) continue 해주었고

이번에 나아갈 방향이 2(대각선)이면 추가로 주변에 벽이 있는지 체크해주었다.

728x90
저작자표시 비영리 변경금지 (새창열림)

'문제 풀이 > 백준 알고리즘' 카테고리의 다른 글

[baekjoon 21924] 도시 건설 (최소 스패닝 트리, 크루스칼, 유니온파인드) (C++)  (0) 2021.06.05
[baekjoon 12852] 1로 만들기 2 (DP) (C++)  (0) 2021.04.19
[baekjoon 1238] 파티 (플로이드와샬, 다익스트라) (C++)  (0) 2021.04.11
[baekjoon 1937] 욕심쟁이 판다 (DFS+DP) (C++)  (0) 2021.04.04
[baekjoon 11404] 플로이드 (플로이드-와샬) (C++)  (0) 2021.03.28
    '문제 풀이/백준 알고리즘' 카테고리의 다른 글
    • [baekjoon 21924] 도시 건설 (최소 스패닝 트리, 크루스칼, 유니온파인드) (C++)
    • [baekjoon 12852] 1로 만들기 2 (DP) (C++)
    • [baekjoon 1238] 파티 (플로이드와샬, 다익스트라) (C++)
    • [baekjoon 1937] 욕심쟁이 판다 (DFS+DP) (C++)
    dev_beomgeun
    dev_beomgeun
    백엔드 개발을 하며 얻은 지식과 경험을 공유합니다. 현재 카카오페이에서 백엔드 엔지니어로 일하고 있습니다.

    티스토리툴바