코드 발전소

[백준 문제집][Python 배우기 (1~50)][2588] 곱셈(세 자리 곱셈 과정 출력) 본문

백준 문제집/Python 배우기(1~50)

[백준 문제집][Python 배우기 (1~50)][2588] 곱셈(세 자리 곱셈 과정 출력)

FeCa 2019. 12. 23. 23:31

이 글에서 살펴볼 문제는 백준 2588번입니다.

주소는 아래와 같습니다.

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

 

2588번: 곱셈

첫째 줄부터 넷째 줄까지 차례대로 (3), (4), (5), (6)에 들어갈 값을 출력한다.

www.acmicpc.net

automata님의 문제집, "Python 배우기 (1~50)"의 9번 문제입니다.

 

 1. 문제 이해                                                                  

 

해당 문제는 다음과 같습니다.

잠시 문제를 간단하게 살펴보면,

"우리가 평소에 끄적이는 세 자리 곱셈 과정을 출력하는 문제"임을 알 수 있습니다.

문제의 시간 제한, 메모리 제한은 다음과 같습니다.

문제의 입력과 출력 조건은 다음과 같습니다.

문제에서 제시된 예제 입출력은 다음과 같습니다.

 

 2. 어떻게 해결할 것인가?                                                  

 

일단 문제를 보자마자 당황하지 않으셨으면 좋겠습니다.

천천히 어떻게 해결할 것인지 살피고 연구하다 보면, 해결의 실마리가 보일 겁니다.

우선, 우리가 평소에 세 자리 곱셈을 필기도구로 끄적이며 계산할 때,

어떠한 과정으로 세 자리 곱셈을 진행하는지 살펴봅시다.

 

​문제에 주어진 "472 X 385" 세 자리 곱셈을 그대로 가져왔습니다.

 

​우선, 위의 사진처럼 가장 위에 있는 472와 385의 일의 자리인 5를 곱하여

2360이라는 결과를 얻고 적어둡니다.

이와 같은 방법으로, 472와 '385의 십의 자리, 백의 자리'를 각각 곱하여 값을 얻어내고 적어둡니다.

마지막으로, 적어둔 수를 모두 더하면 세 자리 곱셈의 결과를 얻을 수 있습니다.

이 과정을 코드로 옮기는 것이 이 문제의 핵심입니다.

제가 가장 먼저 생각나는 방법은,

 

나중에 입력받은 세 자릿수의 일의 자리, 십의 자리, 백의 자리를 변수를 이용해 각각 따로 저장해두고,

먼저 입력받은 세 자릿수에, 저장해둔 각 자리수를 곱하고 모두 더한 값을 출력하는 방법이 떠오릅니다.

(1번 방법)

아니면,

세 자리 자연수를 처음부터 문자열로 두고 인덱싱과 슬라이싱을 하면서 곱해나가는 방법도 있겠습니다.

(2번 방법)

독자분들이 생각하시는 또 다른 방법도 물론 정답이 될 수 있습니다.

프로그래밍에는 최고의 정답이 없고 최적의 정답들이 있기 때문이죠.

1번, 2번 방법을 모두 차례로 구현할 테니, 어떤 방법이 가장 편한지 한번 비교해 보시길 바랍니다.

 3. 문제 해결                                                                  

 

 3 - 1. 1번 방법(변수 저장)                                 

 

우선, 세 자리 정수(자연수) 두 개를 입력받는 코드를 다음과 같이 작성해줍니다.

1
2
= int(input())
= int(input())

 

이제 문제의 조건에 따라 변수 b에 저장된 세 자리 정수의

백의 자리, 십의 자리, 일의 자리를 각각 따로 다른 변수에 저장해 두어야 합니다.

이는 나눗셈 연산자와 나머지 연산자를 적절히 활용하면 해결할 수 있습니다.

그렇게 해결한 코드는 다음과 같습니다.

1
2
3
4
5
6
7
8
# 백의 자리 추출
hundread = int(b / 100)
 
# 십의 자리 추출
ten = int((b % 100/ 10)
 
# 일의 자리 추출
one = int(b % 10)

 

이제 변수 hundread에 백의 자리가, 변수 ten에 십의 자리가, 변수 one에 일의 자리가 저장되었습니다.

다음으로 할 것은, 변수 a에 저장된 세 자리 정수를 각각의 자리 수와 곱하고 그 값을 출력하는 것입니다.

print() 함수를 사용하여 괄호 안에 곱한 값들을 넣어주기만 하면 됩니다.

구현은 다음과 같이 할 수 있겠습니다.

1
2
3
print(a * one)
print(a * ten)
print(a * hundread)

 

이제 마지막으로 최종 곱셈 결과를 출력해야 합니다.

print() 함수를 사용하여 괄호 안에 변수 a변수 b에 저장된 값들을 곱하는 연산을 넣어주면 해결됩니다.

1
print(a * b)

 

전체 코드는 다음과 같습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
= int(input())
= int(input())
 
# 백의 자리 추출
hundread = int(b / 100)
 
# 십의 자리 추출
ten = int((b % 100/ 10)
 
# 일의 자리 추출
one = int(b % 10)
 
print(a * one)
print(a * ten)
print(a * hundread)
 
print(a * b)

 

 3 - 2. 2번 방법(문자열 인덱싱, 슬라이싱)               

 

우선 세 자리 정수(자연수) 두 개를 다음과 같이 입력받습니다.

1
2
= int(input())
= input()

 

변수 b를 굳이 정수로 입력받지 않은 이유는,

변수 b에 저장되는 세 자리 정수를 문자열로 저장함으로써

인덱싱 혹은 슬라이싱을 통해 바로바로 n 자리수에 접근하기 위함입니다.

이제 인덱싱 혹은 슬라이싱으로 바로 n 자리수에 접근 가능하니,

print() 함수로 출력만 해주면 되겠습니다.

다음과 같이 구현할 수 있겠죠?

1
2
3
4
5
6
7
8
9
10
11
# 세 자릿수 X 일의 자리
print(a * int(b[2]))
 
# 세 자릿수 X 십의 자리
print(a * int(b[1]))
 
# 세 자릿수 X 백의 자리
print(a * int(b[0]))
 
# 세 자릿수 곱셈 결과
print(a * int(b))

 

따라서 전체 코드는 다음과 같습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
= int(input())
= input()
 
# 세 자릿수 X 일의 자리
print(a * int(b[2]))
 
# 세 자릿수 X 십의 자리
print(a * int(b[1]))
 
# 세 자릿수 X 백의 자
print(a * int(b[0]))
 
# 세 자릿수 곱셈 결과 출력
print(a * int(b))

 

 4. 코드 제출 및 결과                                                        

 

​위의 결과가 2번 방법, 아래의 결과가 1번 방법입니다.

시간은 문자열 인덱싱, 슬라이싱 방법이 아주 약간 더 오래 걸렸네요.

두 방법 모두 정답임을 확인할 수 있습니다.

 

 

 5. 문제의 정답 비율                                                         

 

정답 비율은 59.075% 로, 평범한 비율을 보여주고 있습니다.

 

 6. 다른 정답자들과의 코드 비교                                          

 

정답자들의 코드는 대부분 비슷하거나 동일하므로 생략합니다.

오답자들의 대표적인 코드는 다음과 같습니다.

대부분의 오답자분들이 위와 같이 작성하셨습니다.

머릿속에 대략의 알고리즘은 짜여 있으나, 5번째 줄과 6번째 줄에서 실수를 하셨습니다.

오답자분이 생각하신 내용은 다음과 같을 것입니다.

5번째 줄은 변수 s_num을 100으로 나눈 나머지, 즉 십의 자리 숫자에서 일의 자리 숫자를 빼는 것이고,

6번째 줄은 변수 s_num에서 (십의 자리 숫자 x 10)과 일의 자리 숫자를 빼어 백의 자리 숫자를 구합니다.

얼핏 보면 무엇이 문제인지 모를 수 있지만, 자세히 살펴보면 문제가 보입니다.

5번째 줄은 십의 자리 숫자에서 일의 자리 숫자를 빼는 것이 아니라

십의 자리 숫자에 10을 곱한 값에서 일의 자리 숫자를 빼는 것이고,

마찬가지로 6번째 줄의 결과는 백의 자리 숫자에 100을 곱한 값이 됩니다.

이를 그대로 변수 f_num에 저장된 세 자리 정수와 곱해버리니 출력 조건에 위반된 것입니다.

충분히 할 수 있는 사소한 실수들이니,

조금 더 유심히 문제 조건과 작성한 코드를 확인할 필요가 있겠습니다.

 

 7. 결론                                                                         

독자분들은 1번 방법과 2번 방법 중 어느 방법이 더 좋다고 생각하시나요?

저는 1번 방법이 친숙하게 다가오네요.

물론, 정답은 없으니 편한 방법으로 코딩을 즐겨주시면 됩니다.

이 글을 읽고 독자분 스스로 더 편한 방법을 찾게 되신다면 더할 나위 없겠죠.

긴 글 읽어주신 여러분들께 진심으로 감사드립니다.

좋은 날 되세요.