F.R.I.D.A.Y.

BAEKJOON 2839: 설탕 배달 for C 본문

DEV/Algorithm

BAEKJOON 2839: 설탕 배달 for C

F.R.I.D.A.Y. 2019. 4. 5. 23:51
반응형

문제

 상근이는 요즘 설탕공장에서 설탕을 배달하고 있다. 상근이는 지금 사탕가게에 설탕을 정확하게 N킬로그램을 배달해야 한다. 설탕공장에서 만드는 설탕은 봉지에 담겨져 있다. 봉지는 3킬로그램 봉지와 5킬로그램 봉지가 있다.

 상근이는 귀찮기 때문에, 최대한 적은 봉지를 들고 가려고 한다. 예를 들어, 18킬로그램 설탕을 배달해야 할 때, 3킬로그램 봉지 6개를 가져가도 되지만, 5킬로그램 3개와 3킬로그램 1개를 배달하면, 더 적은 개수의 봉지를 배달할 수 있다.

 상근이가 설탕을 정확하게 N킬로그램 배달해야 할 때, 봉지 몇 개를 가져가면 되는지 그 수를 구하는 프로그램을 작성하시오.

 

2839번: 설탕 배달

문제 상근이는 요즘 설탕공장에서 설탕을 배달하고 있다. 상근이는 지금 사탕가게에 설탕을 정확하게 N킬로그램을 배달해야 한다. 설탕공장에서 만드는 설탕은 봉지에 담겨져 있다. 봉지는 3킬로그램 봉지와 5킬로그램 봉지가 있다. 상근이는 귀찮기 때문에, 최대한 적은 봉지를 들고 가려고 한다. 예를 들어, 18킬로그램 설탕을 배달해야 할 때, 3킬로그램 봉지 6개를 가져가도 되지만, 5킬로그램 3개와 3킬로그램 1개를 배달하면, 더 적은 개수의 봉지를 배달할 수

www.acmicpc.net


 이 문제는 3KG의 봉지 때문에 의외의 난관이 생기는 문제입니다. 5KG의 봉지만 있었다면 손쉽게 코드를 짰을테지만 3KG의 봉지 하나가 이 문제를 복잡하게(?) 만들죠. 그렇지만 생각해보면 간단한 문제입니다.

 

 일단 입력을 받습니다.

#include <stdio.h>

int main(void) {
	int mass; // 입력
	scanf("%d", &mass);

	return 0;
}

 그리고 입력받은 값에서 5KG, 3KG을 넣을 수 있는만큼 넣습니다.

#include <stdio.h>

int main(void) {
	int mass; //입력
	scanf("%d", &mass);

	int b5, b3;	// n KG 봉지 수

	b5 = mass / 5;	// 5KG 봉지 수를 구합니다.
	mass %= 5;	// 5KG 봉지를 만들고 난 나머지를 구합니다.

	b3 = mass / 3;	// 나머지에서 만들 수 있는 3KG 봉지 수를 구합니다.
	mass %= 3;	// 3KG 봉지를 만들고 난 나머지를 구합니다.

	return 0;
}

 이제 그럼 mass에는 무조건 [0, 1, 2]중 하나의 값이 저장되어있습니다. 3으로 나눈 나머지이기 때문이죠.

 이제 이 나머지를 처리해봅니다. 5KG 봉지를 하나 뜯으면 나머지는 mass + 5 가 됩니다. 이 때에는 mass가 2인 것으로 가정하죠. mass + 5 = 7이므로 3으로 나누면 몫은 2, 나머지는 1이 됩니다. 이 과정을 한번 더 거치게 되면 또 몫은 2, 나머지는 0이 남게 됩니다.

 이 로직을 코드에 담아보겠습니다.

	while (mass) {	// 5와 3으로 나누어지지 않으면
		--b5; // 5KG 봉지 하나를 뜯어서
		mass += 5; // 남은 것에 5를 더해준 뒤
		b3 += mass / 3; // 나머지를 3으로 나눈 몫을 3KG으로 묶고
		mass %= 3; // 3KG으로 나눈 나머지를 구합니다.

	}

 이 때, b5(5KG 봉지 수)의 수가 0이 되면 나머지가 0이 아니더라도 나와야합니다. 즉, 5와 3을 가지고 나눌 수 없는 수인 것입니다.

	while (mass) {	// 5와 3으로 나누어지지 않으면
		if (b5 <= 0) break; // 5KG 봉지 수가 0 이하이면 반복을 종료합니다.
		--b5; // 5KG 봉지 하나를 뜯어서
		mass += 5; // 남은 것에 5를 더해준 뒤
		b3 += mass / 3; // 나머지를 3으로 나눈 몫을 3KG으로 묶고
		mass %= 3; // 3KG으로 나눈 나머지를 구합니다.

	}

 (1)if ( b5 <= 0) break; 코드는 항상 --b5; 위에 위치해야합니다. 이유는 인풋 값으로 4를 작성하게 되면 알 수 있습니다. 아래 코드는 인풋으로 4가 들어왔을 때, (1)코드가 while 하단에 위치하는 경우를 처리한 경우입니다.

#include <stdio.h>

int main(void) {
	int mass; //입력
	scanf("%d", &mass);

	int b5, b3;	// n KG 봉지 수

	b5 = mass / 5; // 4 / 5 = 0
	mass %= 5;	// 4 % 5 = 4

	b3 = mass / 3; // 4 / 3 = 1
	mass %= 3; // 4 % 3 = 1

	while (mass) {	// mass == 1 이므로 시행
		--b5; // --b5 = 0 - 1 = -1
		mass += 5; // mass + 5 = 6
		b3 += mass / 3; // b3 + 2 = 3
		mass %= 3; // 6 % 3 = 0
		if (b5 <= 0) break; // b5가 0보다 작으므로 탈출
	}


	return 0;
}

 위 코드의 결과는 [b5 = -1, b3 = 3]으로 비정상 값이 도출됩니다. 따라서 (1)의 코드는 꼭 while 바로 뒤에 붙어야겠습니다.

 

 b5가 0이면 무조건 탈출하게 되므로 while 밖에서 mass, 즉 나머지가 존재하는지 판단하면 됩니다.

#include <stdio.h>

int main(void) {
	int mass; //입력
	scanf("%d", &mass);

	int b5, b3;	// n KG 봉지 수

	b5 = mass / 5;	// 5KG 봉지 수를 구합니다.
	mass %= 5;		// 5KG 봉지를 만들고 난 나머지를 구합니다.

	b3 = mass / 3;	// 나머지에서 만들 수 있는 3KG 봉지 수를 구합니다.
	mass %= 3;		// 3KG 봉지를 만들고 난 나머지를 구합니다.

	while (mass) {	// 5와 3으로 나누어지지 않으면
		if (b5 <= 0) break; // 5KG 봉지 수가 0 이하이면 반복을 종료합니다.
		--b5; // 5KG 봉지 하나를 뜯어서
		mass += 5; // 남은 것에 5를 더해준 뒤
		b3 += mass / 3; // 나머지를 3으로 나눈 몫을 3KG으로 묶고
		mass %= 3; // 3KG으로 나눈 나머지를 구합니다.

	}

	if (mass) printf("-1"); // 나머지가 존재하면 -1
	else printf("%d", b5 + b3); // 아니면 5KG, 3KG 봉지 수를 출력

	return 0;
}

 문제를 포스트하니 이 문제가 정답률이 낮은 문제임을 확인했습니다.

채 30%가 되지 않네요

728x90
반응형

'DEV > Algorithm' 카테고리의 다른 글

BAEKJOON 10845 : 큐 for C  (0) 2019.10.31
BAEKJOON 9012 : 괄호 for C  (0) 2019.10.27
BAEKJOON 4673 : 셀프 넘버 for C  (0) 2019.10.11
BAEKJOON 1065 : 한수 for C  (0) 2019.10.11
BAEKJOON 1009 : 분산처리 for C  (0) 2019.04.06
Comments