SWLUG/λ°±μ€€ BEAKJOON

[C] λ°±μ€€ BAEKJOON 2798번: λΈ”λž™μž­

waterproof 2023. 10. 6. 02:03

 

 

https://www.acmicpc.net/problem/2798

 

2798번: λΈ”λž™μž­

첫째 쀄에 μΉ΄λ“œμ˜ 개수 N(3 ≤ N ≤ 100)κ³Ό M(10 ≤ M ≤ 300,000)이 주어진닀. λ‘˜μ§Έ μ€„μ—λŠ” μΉ΄λ“œμ— μ“°μ—¬ μžˆλŠ” μˆ˜κ°€ 주어지며, 이 값은 100,000을 λ„˜μ§€ μ•ŠλŠ” μ–‘μ˜ μ •μˆ˜μ΄λ‹€. 합이 M을 λ„˜μ§€ μ•ŠλŠ” μΉ΄λ“œ 3μž₯

www.acmicpc.net

 


[1] 문제

 

 

문제

μΉ΄μ§€λ…Έμ—μ„œ 제일 인기 μžˆλŠ” κ²Œμž„ λΈ”λž™μž­μ˜ κ·œμΉ™μ€ μƒλ‹Ήνžˆ 쉽닀. μΉ΄λ“œμ˜ 합이 21을 λ„˜μ§€ μ•ŠλŠ” ν•œλ„ λ‚΄μ—μ„œ, μΉ΄λ“œμ˜ 합을 μ΅œλŒ€ν•œ 크게 λ§Œλ“œλŠ” κ²Œμž„μ΄λ‹€. λΈ”λž™μž­μ€ μΉ΄μ§€λ…Έλ§ˆλ‹€ λ‹€μ–‘ν•œ κ·œμ •μ΄ μžˆλ‹€.

ν•œκ΅­ 졜고의 λΈ”λž™μž­ 고수 김정인은 μƒˆλ‘œμš΄ λΈ”λž™μž­ κ·œμΉ™μ„ λ§Œλ“€μ–΄ 상근, μ°½μ˜μ΄μ™€ κ²Œμž„ν•˜λ €κ³  ν•œλ‹€.

김정인 λ²„μ „μ˜ λΈ”λž™μž­μ—μ„œ 각 μΉ΄λ“œμ—λŠ” μ–‘μ˜ μ •μˆ˜κ°€ μ“°μ—¬ μžˆλ‹€. κ·Έ λ‹€μŒ, λ”œλŸ¬λŠ” Nμž₯의 μΉ΄λ“œλ₯Ό λͺ¨λ‘ μˆ«μžκ°€ 보이도둝 λ°”λ‹₯에 λ†“λŠ”λ‹€. 그런 후에 λ”œλŸ¬λŠ” 숫자 M을 크게 μ™ΈμΉœλ‹€.

이제 ν”Œλ ˆμ΄μ–΄λŠ” μ œν•œλœ μ‹œκ°„ μ•ˆμ— Nμž₯의 μΉ΄λ“œ μ€‘μ—μ„œ 3μž₯의 μΉ΄λ“œλ₯Ό 골라야 ν•œλ‹€. λΈ”λž™μž­ λ³€ν˜• κ²Œμž„μ΄κΈ° λ•Œλ¬Έμ—, ν”Œλ ˆμ΄μ–΄κ°€ κ³ λ₯Έ μΉ΄λ“œμ˜ 합은 M을 λ„˜μ§€ μ•ŠμœΌλ©΄μ„œ Mκ³Ό μ΅œλŒ€ν•œ κ°€κΉκ²Œ λ§Œλ“€μ–΄μ•Ό ν•œλ‹€.

Nμž₯의 μΉ΄λ“œμ— 써져 μžˆλŠ” μˆ«μžκ°€ μ£Όμ–΄μ‘Œμ„ λ•Œ, M을 λ„˜μ§€ μ•ŠμœΌλ©΄μ„œ M에 μ΅œλŒ€ν•œ κ°€κΉŒμš΄ μΉ΄λ“œ 3μž₯의 합을 ꡬ해 좜λ ₯ν•˜μ‹œμ˜€.

μž…λ ₯

첫째 쀄에 μΉ΄λ“œμ˜ 개수 N(3 ≤ N ≤ 100)κ³Ό M(10 ≤ M ≤ 300,000)이 주어진닀. λ‘˜μ§Έ μ€„μ—λŠ” μΉ΄λ“œμ— μ“°μ—¬ μžˆλŠ” μˆ˜κ°€ 주어지며, 이 값은 100,000을 λ„˜μ§€ μ•ŠλŠ” μ–‘μ˜ μ •μˆ˜μ΄λ‹€.

합이 M을 λ„˜μ§€ μ•ŠλŠ” μΉ΄λ“œ 3μž₯을 찾을 수 μžˆλŠ” 경우만 μž…λ ₯으둜 주어진닀.

좜λ ₯

첫째 쀄에 M을 λ„˜μ§€ μ•ŠμœΌλ©΄μ„œ M에 μ΅œλŒ€ν•œ κ°€κΉŒμš΄ μΉ΄λ“œ 3μž₯의 합을 좜λ ₯ν•œλ‹€.

예제 μž…λ ₯ 1 λ³΅μ‚¬

5 21
5 6 7 8 9

예제 좜λ ₯ 1 λ³΅μ‚¬

21

예제 μž…λ ₯ 2 λ³΅μ‚¬

10 500
93 181 245 214 315 36 185 138 216 295

예제 좜λ ₯ 2 λ³΅μ‚¬

497

 

 

 

 


[2] μ •λ‹΅ 및 ν•΄μ„€

 

 

 

# μ •λ‹΅ μ½”λ“œ

 

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

int main(void) {

	int N, M;
	int a[100];
	int max = 0, sum = 0;


	scanf("%d %d", &N, &M);

	for (int i = 0; i < N; i++) {
		scanf("%d", &a[i]);
	}

	for (int i = 0; i < N - 2; i++) {
		for (int j = i + 1; j < N - 1; j++) {
			for (int k = j + 1; k < N; k++) {
				sum = a[i] + a[j] + a[k];
				if ((sum > max) && (sum <= M)) {
					max = sum;
				}
			}
		}
	}

	printf("%d", max);

	return 0;

}

 

 

# 해석

 

for문이 μ„Έ 번 μ€‘μ²©λœ λ°˜λ³΅λ¬Έμ— λŒ€ν•΄ μ„€λͺ…ν•˜κ² λ‹€.

이 λΆ€λΆ„μ—μ„œλŠ” λ°°μ—΄ aμ—μ„œ κ°€λŠ₯ν•œ λͺ¨λ“  μ„Έ 숫자 쑰합을 ν™•μΈν•˜κ³ , κ·Έ μ€‘μ—μ„œ 합이 M μ΄ν•˜μΈ κ°€μž₯ 큰 값을 μ°ΎλŠ”λ‹€.

문제의 핡심 μ•Œκ³ λ¦¬μ¦˜μ΄λ‹€.

 

 

for (int i = 0; i < N - 2; i++): 첫 번째 λ°˜λ³΅λ¬Έμ€ iλ₯Ό 0λΆ€ν„° N - 2κΉŒμ§€ μ¦κ°€μ‹œν‚¨λ‹€. μ΄λŠ” λ°°μ—΄μ˜ 첫 번째 μ›μ†ŒλΆ€ν„° λ’€μ—μ„œ 두 번째 μ›μ†ŒκΉŒμ§€λ₯Ό κΈ°μ€€μœΌλ‘œ μ„ νƒν•˜λŠ” 역할을 ν•œλ‹€.

 

for (int j = i + 1; j < N - 1; j++): 두 번째 λ°˜λ³΅λ¬Έμ€ jλ₯Ό i + 1λΆ€ν„° N - 1κΉŒμ§€ μ¦κ°€μ‹œν‚¨λ‹€. μ΄λŠ” 기쀀이 λ˜λŠ” i번째 μ›μ†Œ λ‹€μŒλΆ€ν„° λ§ˆμ§€λ§‰μ—μ„œ 두 번째 μ›μ†ŒκΉŒμ§€λ₯Ό μ„ νƒν•˜λŠ” 역할을 ν•œλ‹€.

 

for (int k = j + 1; k < N; k++): μ„Έ 번째 λ°˜λ³΅λ¬Έμ€ kλ₯Ό j + 1λΆ€ν„° NκΉŒμ§€ μ¦κ°€μ‹œν‚¨λ‹€. μ΄λŠ” 기쀀이 λ˜λŠ” j번째 μ›μ†Œ λ‹€μŒλΆ€ν„° λ§ˆμ§€λ§‰ μ›μ†ŒκΉŒμ§€λ₯Ό μ„ νƒν•˜λŠ” 역할을 ν•œλ‹€.

 

 

이제, 이 μ„Έ 개의 반볡문이 λ™μž‘ν•˜λ©΄μ„œ i, j, kλŠ” μ„œλ‘œ λ‹€λ₯Έ λ°°μ—΄μ˜ 인덱슀λ₯Ό κ°€λ¦¬ν‚€κ²Œ λœλ‹€. (λ‚΄κ°€ λ– μ˜¬λ¦¬μ§€ λͺ»ν•œ λΆ€λΆ„)

이 μΈλ±μŠ€λ“€μ„ μ‚¬μš©ν•˜μ—¬ λ°°μ—΄ aμ—μ„œ μ„Έ 개의 숫자λ₯Ό μ„ νƒν•˜κ³ (a[i], a[j], a[k]), μ΄λ“€μ˜ 합을 κ³„μ‚°ν•˜μ—¬ sum에 μ €μž₯ν•œλ‹€.

 


그런 λ‹€μŒ, if문을 μ‚¬μš©ν•˜μ—¬ sum이 ν˜„μž¬κΉŒμ§€μ˜ μ΅œλŒ€κ°’ max보닀 크고, λ™μ‹œμ— M μ΄ν•˜μΈμ§€ ν™•μΈν•œλ‹€.

λ§Œμ•½ κ·Έλ ‡λ‹€λ©΄, maxλ₯Ό sum으둜 μ—…λ°μ΄νŠΈν•œλ‹€.

μ΄λ ‡κ²Œ ν•˜λ©΄ ν˜„μž¬κΉŒμ§€ ν™•μΈν•œ μ‘°ν•© μ€‘μ—μ„œ κ°€μž₯ 큰 합이 max에 μ €μž₯λœλ‹€.

 

 

λ§ˆμ§€λ§‰μœΌλ‘œ, λͺ¨λ“  반볡문이 μ‹€ν–‰λœ ν›„μ—λŠ” max에 μ €μž₯된 값이 κ°€μž₯ 큰 ν•©μ΄λ―€λ‘œ 이λ₯Ό 좜λ ₯ν•œλ‹€.

 


μ΄λ ‡κ²Œ ν•΄μ„œ ν”„λ‘œκ·Έλž¨μ€ λ°°μ—΄ aμ—μ„œ κ°€λŠ₯ν•œ λͺ¨λ“  μ„Έ 숫자 μ‘°ν•© μ€‘μ—μ„œ 합이 M μ΄ν•˜μΈ κ°€μž₯ 큰 값을 μ°Ύκ³  좜λ ₯ν•œλ‹€.

 

 

 

 


[3] λŠλ‚€ 점

 

 

 

λ°°μ—΄κ³Ό for문을 μ΄μš©ν•΄μ„œ μž…λ ₯받은 숫자 크기만큼 scanfλ₯Ό μ΄μš©ν•˜λŠ” 건 전에 ν’€μ—ˆλ˜ 문제 덕뢄에 μ•Œκ³  μžˆμ—ˆλ‹€.

 

 

λ°°μ—΄ aμ—μ„œ κ°€λŠ₯ν•œ λͺ¨λ“  μ„Έ 숫자 쑰합을 ν™•μΈν•˜λŠ” μ•Œκ³ λ¦¬μ¦˜μ— λŒ€ν•œ 아이디어가 도무지 λ– μ˜€λ₯΄μ§€ μ•Šμ•˜λ‹€.

 

브루트포슀 μ•Œκ³ λ¦¬μ¦˜μ„ μ΄μš©ν•œλ‹€κ³  ν•œλ‹€.

 

그런데 그게 뭔지 λͺ°λΌμ„œ μ „ν˜€ 도움이 λ˜μ§€ μ•Šμ•˜λ‹€...

 

ꡬ글링을 톡해 문제λ₯Ό ν’€μ—ˆλŠ”λ°

 

μ •λ‹΅ μ½”λ“œλ₯Ό ν™•μΈν•˜λ‹ˆ λ°˜λ³΅λ¬Έμ„ μ„Έ 번 μ‚¬μš©ν•˜λ©΄μ„œ λͺ¨λ“  경우의 수λ₯Ό λ§Œλ“€μ–΄λ‚΄λŠ” 아이디어λ₯Ό λ– μ˜¬λ¦¬λŠ” 게 관건인 것 κ°™μ•˜λ‹€.

 

μ‚¬μš©ν•˜λŠ” 문법은 배운 λ‚΄μš©μΈλ° μ‹€μ œλ‘œ μ‚¬μš©ν•΄μ„œ 문제λ₯Ό ν’€μ–΄λ‚΄λŠ” 과정이 μ–΄λ €μš΄ 것 κ°™λ‹€,..

 

 

 


[4] μΆ”κ°€ ν•™μŠ΅

 

 

 

https://hawaiian-pizza-it.tistory.com/39

 

[μ•Œκ³ λ¦¬μ¦˜ κΈ°λ³Έ] μ™„μ „ 탐색 (브루트 포슀 Brute Force)

μ™„μ „ 탐색, 브루트 포슀(Brute Force) Brute Force μ§μ—­ν•˜λ©΄ μ§μŠΉκ°™μ€ 힘, λ¬΄μ‹ν•œ νž˜μ΄λΌλŠ” λœ»μ΄λ‹€. μ™„μ „ νƒμƒ‰μ΄λΌλŠ” μ΄λ¦„μ—μ„œλ„ μ•Œ 수 μžˆλ“―μ΄ ν•˜λ‚˜λΆ€ν„° μ—΄κΉŒμ§€ λͺ¨λ“  경우λ₯Ό λ‹€ νƒμƒ‰ν•˜λŠ” μ•Œκ³ λ¦¬μ¦˜μ΄λ‹€.

hawaiian-pizza-it.tistory.com

 

 

브루트포슀 μ•Œκ³ λ¦¬μ¦˜μ€ ... κ±°μ°½ν•œ μ΄λ¦„λ§ŒνΌ μ—„μ²­λ‚œ μ•Œκ³ λ¦¬μ¦˜μ€ μ•„λ‹ˆκ³ 

 

 

Brute Force μ§μ—­ν•˜λ©΄ μ§μŠΉκ°™μ€ 힘, λ¬΄μ‹ν•œ νž˜μ΄λΌλŠ” λœ»μ΄λ‹€.
μ™„μ „ νƒμƒ‰μ΄λΌλŠ” μ΄λ¦„μ—μ„œλ„ μ•Œ 수 μžˆλ“―μ΄ ν•˜λ‚˜λΆ€ν„° μ—΄κΉŒμ§€ λͺ¨λ“  경우λ₯Ό λ‹€ νƒμƒ‰ν•˜λŠ” μ•Œκ³ λ¦¬μ¦˜μ΄λ‹€.
 
λͺ¨λ“  경우λ₯Ό νƒμƒ‰ν•˜λ‹ˆ λ‹Ήμ—°νžˆ 정닡을 찾을 수 μžˆλ‹€.

 

라고 ν•œλ‹€.

주둜 λ°˜λ³΅λ¬Έμ„ μ€‘μ²©ν•˜μ—¬ μ‚¬μš©ν•  수 μžˆλ‹€κ³  ν•œλ‹€.

그리고 μ•”ν˜Έν•΄λ… κΈ°λ²•μœΌλ‘œλ„ 많이 μ‚¬μš©λœλ‹€κ³  ν•œλ‹€.