박오이님
무미건조한 개발자
박오이님
전체 방문자
오늘
어제
  • 뭥미 (101)
    • 프로젝트 (8)
      • 자가 보호 (3)
      • 주식 시장 분석 도구 (5)
    • 보안 (7)
      • 개론 (2)
      • 웹 (2)
      • 시스템 (2)
    • 개발 (69)
      • C++ (12)
      • Win32 (7)
      • MFC (2)
      • 자료구조 (8)
      • 알고리즘 (22)
      • 백준 (9)
      • 프로그래머스 (4)
      • LeetCode (0)
      • 개발자 면접 준비 (4)
      • OpenGL (1)
    • 서적 (13)
      • Effective C++ (9)
      • Effective Modern C++ (4)
    • 관심사 (4)
      • 재테크 (4)

블로그 메뉴

  • 홈
  • 방명록

공지사항

인기 글

태그

  • 안경잡이개발자
  • 최소간선비용
  • 윈도우프로그래밍
  • 윈도우
  • 나동빈
  • JSON
  • 프로세스메모리
  • 알고리즘
  • 플로이드와샬알고리즘 #최단경로 #백준 #알고리즘 #개발 #C #C++
  • 에라토스테네스의 체 #C #C++ #개발 #알고리즘 #BFS #DFS #백준 #백준알고리즘
  • C
  • 윈도우시스템프로그래밍
  • CPP
  • 에라토스테네스의 체 #알고리즘 #개발 #C #C++ #소수 #소수판별
  • Functional
  • 크루스칼알고리즘
  • 시스템프로그래밍
  • 윈도우개발자
  • 코딩컨벤션
  • 동빈나
  • std
  • C++
  • jsoncpp
  • DFS #BFS #알고리즘 #프로그래밍 #코딩테스트 #코딩 #C++ #C
  • 나동빈 #알고리즘 #동빈나
  • vcpkg
  • 백준 #알고리즘 #플로이드와샬 #DFS #BFS #C #C++
  • 개발
  • 합집합찾기
  • EffectiveC++

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
박오이님

무미건조한 개발자

개발/백준

백준 13460번: 구슬 탈출 2

2019. 10. 14. 18:09

문제 링크: https://www.acmicpc.net/problem/13460

 

13460번: 구슬 탈출 2

첫 번째 줄에는 보드의 세로, 가로 크기를 의미하는 두 정수 N, M (3 ≤ N, M ≤ 10)이 주어진다. 다음 N개의 줄에 보드의 모양을 나타내는 길이 M의 문자열이 주어진다. 이 문자열은 '.', '#', 'O', 'R', 'B' 로 이루어져 있다. '.'은 빈 칸을 의미하고, '#'은 공이 이동할 수 없는 장애물 또는 벽을 의미하며, 'O'는 구멍의 위치를 의미한다. 'R'은 빨간 구슬의 위치, 'B'는 파란 구슬의 위치이다. 입력되는 모든 보드

www.acmicpc.net

문제 해결 방법: BFS 또는 DFS인데, 기울이기가 한 칸씩 이동개념이랑 다르다.
테스트 케이스 2번째로 한 칸씩 이동한다는 것으로 생각하면 10번만에 가지못한다.
--> 즉, 기울이기 라는 개념을 유의하고 풀 것!

/*
문제번호 : 13460
문제링크 : https://www.acmicpc.net/problem/13460
문제이름 : 구슬탈출2

풀이방법 : 기울이기를 고려한 BFS

*/

#include <iostream>
#include <algorithm>
#include <queue>

using namespace std;

typedef struct stINFO {
	int ry;
	int rx;
	int by;
	int bx;
	int count;
}INFO;

int N, M;				// 세로, 가로 변수

INFO start;

char cMap[11][11];		// 구슬 맵

// 서, 북, 동, 남
int dy[4] = { 0, -1, 0, 1 };
int dx[4] = { -1, 0, 1, 0 };

int Solve()
{
	queue<INFO> q;
	bool bVisit[10][10][10][10] = { false, };	// 방문기록
	q.push(start);

	bVisit[start.ry][start.rx][start.by][start.bx] = true;

	int nRet = -1;

	while (!q.empty())
	{
		INFO cur = q.front();
		q.pop();

		if (cur.count > 10) break;
		if (cMap[cur.ry][cur.rx] == 'O' && cMap[cur.by][cur.bx] != 'O')
		{
			nRet = cur.count;
			break;
		}

		for (int i = 0; i < 4; i++)
		{
			int next_ry = cur.ry;
			int next_rx = cur.rx;
			int next_by = cur.by;
			int next_bx = cur.bx;

			// 빨간 구슬 이동
			while (1)
			{
				if (cMap[next_ry][next_rx] != '#' && cMap[next_ry][next_rx] != 'O')
				{
					next_ry = next_ry + dy[i];
					next_rx = next_rx + dx[i];
				}
				else
				{
					if (cMap[next_ry][next_rx] == '#')
					{
						next_ry = next_ry - dy[i];
						next_rx = next_rx - dx[i];
					}
					break;
				}
			}
			// 파란 구슬 이동
			while (1)
			{
				if (cMap[next_by][next_bx] != '#' && cMap[next_by][next_bx] != 'O')
				{
					next_by = next_by + dy[i];
					next_bx = next_bx + dx[i];
				}
				else
				{
					if (cMap[next_by][next_bx] == '#')
					{
						next_by = next_by - dy[i];
						next_bx = next_bx - dx[i];
					}
					break;
				}
			}

			// 구멍은 아니지만, 기울여서 서로가 같은위치에 있을 때,
			if (next_ry == next_by && next_rx == next_bx)
			{
				if (cMap[next_ry][next_rx] != 'O')
				{
					int red_dist = abs(next_ry - cur.ry) + abs(next_rx - cur.rx);
					int blue_dist = abs(next_by - cur.by) + abs(next_bx - cur.bx);

					if (red_dist > blue_dist)
					{
						next_ry -= dy[i];
						next_rx -= dx[i];
					}
					else
					{
						next_by -= dy[i];
						next_bx -= dx[i];
					}
				}
			}

			if (bVisit[next_ry][next_rx][next_by][next_bx] == false)
			{
				bVisit[next_ry][next_rx][next_by][next_bx] = true;
				INFO next;

				next.ry = next_ry;
				next.rx = next_rx;
				next.by = next_by;
				next.bx = next_bx;
				next.count = cur.count + 1;
				q.push(next);
			}
		}
	}
	
	// 메모리 정리
	while (!q.empty())
	{
		q.pop();
	}

	return nRet;
}


int main(void)
{

	int nResult = 0;

	cin >> N >> M;

	for (int i = 0; i < N; i++)
	{
		for (int j = 0; j < M; j++)
		{
			cin >> cMap[i][j];
		}
	}

	for (int i = 0; i < N; i++)
	{
		for (int j = 0; j < M; j++)
		{
			if (cMap[i][j] == 'R')
			{
				start.ry = i;
				start.rx = j;
			}
			if (cMap[i][j] == 'B')
			{
				start.by = i;
				start.bx = j;
			}
		}
	}

	start.count = 0;

	nResult = Solve();

	cout << nResult << endl;

	return 0;
}
저작자표시 (새창열림)

'개발 > 백준' 카테고리의 다른 글

백준 10451번: 순열 사이클  (0) 2019.09.26
백준 9466번: 텀 프로젝트  (0) 2019.09.26
백준 1325번: 효율적인 해킹  (0) 2019.09.24
백준 1963번: 소수 경로  (0) 2019.09.02
백준 1389번: 케빈 베이컨의 6단계 법칙  (0) 2019.09.01
    '개발/백준' 카테고리의 다른 글
    • 백준 10451번: 순열 사이클
    • 백준 9466번: 텀 프로젝트
    • 백준 1325번: 효율적인 해킹
    • 백준 1963번: 소수 경로
    박오이님
    박오이님
    긍정도 아니고 부정도 아닌 0

    티스토리툴바