재바기
JaeTech
재바기
전체 방문자
오늘
어제
  • 분류 전체보기 (77)
    • Computer Vision (2)
    • 선형대수학 (9)
    • Papers (1)
    • 알쓸신잡 (7)
    • 삽질 기록 (0)
    • 3D\Multiview Geometry (10)
      • CS231A (10)
    • Computer Science (46)
      • Algorithm (14)
      • JavaScript (3)
      • C || C++ (5)
      • Git || Github (3)
      • Linux (2)
      • DL || ML (5)
      • Operating System (8)
      • Computer Network (0)
      • Database (1)
      • Effective Python (5)
      • Data Communication (0)
    • 회고 (0)
    • Latex (1)

블로그 메뉴

  • 홈
  • 태그

Github

공지사항

  • 주인장에 대해

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
재바기

JaeTech

(C++) 백준 15686번 [치킨 배달]
Computer Science/Algorithm

(C++) 백준 15686번 [치킨 배달]

2021. 2. 21. 22:36
728x90

안녕하세요 평범한 컴공생입니다.

 

오늘은 백준 15686번 [치킨 배달] 문제 알고리즘입니다.

삼성 SW역량테스트 기출문제입니다.

 

처음 문제를 맞닥뜨리고 집합에서의 조합을 어떻게 컴퓨터 언어로 풀어낼 수 있을까 많이 고민해 보았습니다.

사실 이 문제를 저의 능력으로 푼 것이 아니라 다른 분의 알고리즘을 보고 참고하여 푼 것이라 아직 실력이 정말 많이 ㅈ부족하다는 것을 느낄 수 있었던 문제였습니다.

이 풀이가 아니라 구글링을 통해 보았던 다른 분들의 풀이를 보면 C++의 vector를 많이 활용한 것을 알 수 있었는데 아직 vector 의 개념을 학습하지 않아 vector 개념을 조만간 학습한 후에 다시 이 문제를 접근해 보려고 합니다. 

골드 5 난이도의 문제입니다.

1. 문제 해결 방법 구상하기

 - 크기가 N*N인 도시의 정보와 남겨놓을 치킨집의 개수 M을 입력받아야 하므로 행과 열을 나타낼 이중반복문을 활용해야한다.

 - 만약 일반 가정집 (1)을 입력받았다면 그 행과 열의 정보를 가정집의 배열에 기록해 두어야 하고, 치킨집(2)을 입력받았다면 그 행과 열의 정보를 치킨집의 배열에 기록해 두어야 한다. >> 이를 위해 입력받은 치킨집과 가정집의 개수를 count 해줄 전역변수를 선언해주어야 할 것이고, 행과 열의 정보는 구조체(struct)를 통해 입력받으면 된다.

 - solution 함수를 통해 바로 답을 출력하도록 하고 solution 함수에 문제에서 원하는 치킨 거리를 구하도록 알고리즘을 짜야한다.

 - 입력받은 치킨집의 개수를 전역변수 Cnt_Chicken 이라고 하면 집합 Cnt_Chicken의 원소 중 M개의 원소만 남아있을 경우들만 비교를 해주면 된다. >> 그렇다면 어떻게 M개의 원소, 즉 Cnt_Chicken 콤비네이션 M 의 경우의 수를 표현할 것인가? >> 비트를 통해서 표현해주면 된다.

 - algorithm 라이브러리를 include 하여 min 함수를 사용하여 최단거리를 계속 갱신해주면 될 듯하다.

 

2. 구상한 아이디어를 바탕으로 코딩하기

#include <iostream>
#include <algorithm> // min 함수 사용을 위해

#define BIG_NUM 987654321 // 매우 큰 값을 설정해주어 무조건 첫 경우가 작은 값으로 갱신되도록

using namespace std;

struct location
{
	int row, col;
};	// 입력받은 가정집과 치킨집의 위치정보(행과 열)을 저장하기 위한 구조체

int N, M; // 전역변수로 N, M을 입력받아 solution 함수에 다시 M값을 인자로 넣지 않아도 되도록 함
location House[100], Chicken[13]; // 가정집과 치킨집의 주소정보 저장하는 구조체
int Cnt_House = 0, Cnt_Chicken = 0; 입력받는 치킨집과 가정집의 개수

int abs(int n)
{
	return n >= 0 ? n : -n;
}	// 절댓값을 반환해주는 함수

int bitchk(int n)
{
	int cnt = 0;
	while (n)
	{
		if (n & 1)
			cnt++;
		n = n >> 1;
	}
	return cnt;
}	// Cnt_Chicken 콤비네이션 M 의 경우만 색출해주는 함수
	// n을 이진수로 봤을 때 비트를 이용해 해당 치킨집을 없앨지 말 지를 설정해줄 수 있음

int solution()
{
	int ans = BIG_NUM;
	for (int set = 0; set < (1 << Cnt_Chicken); set++)
	{	// 원소의 개수가 Cnt_Chicken인 집합의 부분집합의 개수는 2의 Cnt_Chicken 제곱이므로
    	// 1 << Cnt_Chicken 해주면 된다.
		if (bitchk(set) == M)
		{
			int sum=0;
			for (int i = 0; i < Cnt_House; i++)
			{
				int distance = BIG_NUM;
				for (int j = 0; j < Cnt_Chicken; j++)
				{
					if (set & (1 << j))
						distance=min(distance,
							abs(House[i].row - Chicken[j].row) + abs(House[i].col - Chicken[j].col));
				}
				sum += distance;
			}
			ans = min(ans, sum);
		}
	}
	return ans;
}

int main()
{
	cin >> N >> M;

	int input;
	for (int i = 0; i < N; i++)
	{
		for (int j = 0; j < N; j++)
		{
			cin >> input;
			if (input == 1)
				House[Cnt_House++] = { i,j };
			else if (input == 2)
				Chicken[Cnt_Chicken++] = { i,j };
		}
	}

	cout << solution() << endl;

	return 0;
}

생각보다 참 난항을 했던 문제였고, 더 공부에 절실히 매달려야 함을 알려준 문제였다. 그리고 삼성 SW 기출문제이므로 멀지 않은 미래에 이러한 문제를 맞닥뜨리게 될텐데, 그 미래에는 당황하지 않고 차분히 해결할 수 있는 실력을 갖춘 개발자로 성장해있기를 바라며 앞으로 더 노력해야겠다.

 

// 피드백 및 문제사항 제기 감사히 받겠습니다.

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

'Computer Science > Algorithm' 카테고리의 다른 글

(C++) 백준 10971번 [외판원 순회2]  (0) 2021.02.28
(C++) 백준 11729번 [하노이 탑 이동 순서]  (0) 2021.02.21
(C++) 백준 2960번 [에라토스테네스의 체]  (0) 2021.02.18
(C++) 백준 2231번 [분해합]  (0) 2021.02.13
(C++) 백준 2798번 [블랙잭]  (0) 2021.02.12
    'Computer Science/Algorithm' 카테고리의 다른 글
    • (C++) 백준 10971번 [외판원 순회2]
    • (C++) 백준 11729번 [하노이 탑 이동 순서]
    • (C++) 백준 2960번 [에라토스테네스의 체]
    • (C++) 백준 2231번 [분해합]
    재바기
    재바기
    재박이의 테크블로그

    티스토리툴바