끄적끄적 코딩
article thumbnail
728x90

조각들을 전부 인접하도록 만들기 위해서
조각을 최소 몇번 움직여야 하는지 찾는 문제입니다.

브루트 포스 방식을 사용했습니다.

1. 조각이 있을 수 있는 모든 경우를 탐색합니다. (인접하지 않는 경우도 포함)
2. 각 경우마다 DFS를 통해서 연결되어 있는지 확인합니다.
3. 연결이 되어 있는 경우 계산된 값을 비교해서 작으면 넣어줍니다.


#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <string>
#define MAX 987654321
using namespace std;

int len;
int result = MAX;
bool visit[7][7];
char map[7][7];
int moveX[4] = { 0, 1, 0, -1 };
int moveY[4] = { 1, 0, -1, 0 };
vector<pair<int, int> > v;

int calc(int a, int b, int c, int d)
{
	return abs(a - c) + abs(b - d);
}

void check(int a, int b)
{
	for (int i = 0; i < 4; ++i) {
		int x = b + moveX[i];
		int y = a + moveY[i];

		if (map[y][x] != '*' || visit[y][x]) {
			continue;
		}
		visit[y][x] = true;

		check(y, x);
	}
}

bool connect() {
	int c = 0;

	memset(visit, 0, sizeof(visit));
	for (int i = 1; i <= 5; ++i) {
		for (int j = 1; j <= 5; ++j) {
			if (map[i][j] == '*' && !visit[i][j]) {
				visit[i][j] = 1;
				++c;
				check(i, j);
			}
		}
	}

	if (c == 1) {
		return true;
	}
	else {
		return false;
	}
}

void DFS(int c, int d)
{
	if (d >= result) {
		return;
	}

	if (c == len) {
		if (connect()) {
			result = min(result, d);
		}
		return;
	}

	for (int i = 1; i <= 5; ++i) {
		for (int j = 1; j <= 5; ++j) {
			if (map[i][j] == '.') {
				map[i][j] = '*';
				DFS(c + 1, d + calc(v[c].first, v[c].second, i, j));
				map[i][j] = '.';
			}
		}
	}
}

int main(int argc, char * argv[])
{
	string s;

	memset(map, ' ', sizeof(map));
	for (int i = 1; i <= 5; ++i) {
		for (int j = 1; j <= 5; ++j) {
			cin >> map[i][j];
			if (map[i][j] == '*') {
				v.push_back(make_pair(i, j));
				map[i][j] = '.';
			}
		}
	}

	len = v.size();
	DFS(0, 0);

	cout << result << endl;

	return 0;
}

'알고리즘' 카테고리의 다른 글

[C++] 백준 1600번 말이 되고픈 원숭이  (0) 2019.11.11
[C++] 백준 4179번 불!  (0) 2019.11.10
[C++] 백준 15707번 exceed or not  (0) 2019.11.07
[C++] 백준 17626번 Four Squares  (0) 2019.11.07
[C++] 백준 2823번 유턴 싫어  (0) 2019.11.07

검색 태그