www.acmicpc.net/group/practice/9883/14
이번 복습 문제는 5번 문제가 단순 for문으로 구현했으면 시간 초과가 나와서 생각을 해야했던 문제였고, 3번 문제가 제일 어려웠을 것이라고 생각합니다.
1. BOJ 2744 대소문자 바꾸기
대문자는 소문자로, 소문자는 대문자로 바꾸라는 문제입니다.
소문자로 만드는 방법은 lower()메소드, 대문자로 만드는 방법은 upper()메소드가 있습니다.
일단 입력값을 받아야 하는데, 문자열로 입력 받으면 값을 바꿀 수 없으니 리스트로 값을 받습니다.
s = list(input())
그리고 이제 for문과 if / else문을 이용하여 소문자일 때는 대문자로 변환시키고, 대문자일 때는 소문자로 변환시켜주면 됩니다.
s = list(input())
for i in range(len(s)):
if s[i] == s[i].upper(): s[i] = s[i].lower()
else: s[i] = s[i].upper()
print(''.join(s))
2. BOJ 7600 문자가 몇갤까
아스키 코드 혹은 딕셔너리로 풀 수 있는 문제입니다.
풀이는 아스키 코드로 하겠습니다.
#을 입력 받기 전까지 계속 입력값을 받아야하므로 while문을 사용합니다. 입력값에 나오는 알파벳은 대소문자를 하나의 문자로 처리한다고 나왔으므로 전부 소문자로 변환 시켜줍시다.
while 1:
s = input().lower()
if s == '#': break
그리고 이제 알파벳의 개수를 세야하는데, 알파벳의 갯수를 기록하는 apb 리스트를 만들어주고 for문을 돌려서 아스키 코드가 97이상 122이하이면 -97을 해주어서 apb 리스트중 해당하는 인덱스에 1을 더해주면 됩니다.
while 1:
s = input().lower()
if s == '#': break
apb = [0]*26
for i in range(len(s)):
if 97 <= ord(s[i]) <= 122:
apb[ord(s[i])-97] += 1
그리고 이제 int형 변수를 하나 선언하여 apb 리스트를 확인하여 1이상의 값이 있을 때 변수에 1을 더해주고 출력해주면 됩니다.
while 1:
s = input().lower()
if s == '#' : break
apb = [0] * 26
for i in range(len(s)):
if 97 <= ord(s[i]) <= 122:
apb[ord(s[i]) - 97] += 1
ans = 0
for i in range(26):
if apb[i] > 0: ans += 1
print(ans)
3. BOJ 9047 6174
숫자를 입력 받아서 몇 번의 연산만에 6174가 나오는지 구하는 문제입니다.
문제를 읽어보니까 2008을 입력 받았는데 8200과 0028로 변환해서 8200 - 0028을 해준다고 하네요.
이것을 보니 2008을 하나하나 떼어서 하나는 내림차순, 하나는 오름차순으로 정렬한 후 숫자들을 다시 붙여서 8200, 0028로 만들 수 있다는 것을 캐치해야 문제를 풀어나갈 수 있습니다.
하나하나 떼어서 정렬해야하므로 입력값은 숫자가 아닌 문자를 가지고 있는 리스트로 해야겠네요. 숫자로 받는다면 8200%10을 리스트에 저장 -> 8200//10 = 820
820%10을 리스트에 저장 -> 820//10 = 82
82%10을 리스트에 저장 -> 82//10 = 8
8%10을 리스트에 저장 -> 8//10 = 0
이렇게 귀찮은 작업을 하고 정렬을 해야해서 그냥 단순하게 문자 리스트로 받아줍시다.
t = int(input())
for i in range(t):
s = list(input())
이제 내림차순과 오름차순을 해야하는데 각각 s_max, s_min으로 저장해서 정렬을 해야합니다. 그전에 먼저 s가 ['6', '1', '7', '4']가 나올 때까지 반복해야하므로 while문을 넣어주고 정렬을 합시다.
t = int(input())
for i in range(t):
s = list(input())
while s != ['6', '1', '7', '4']:
s_max = sorted(s, reverse = True)
s_min = sorted(s)
그리고 이제 s_max와 s_min을 숫자로 변환해야합니다.
숫자로 변환한 값은 s_max는 x로 s_min은 y로 만들겠습니다.
for i in range(t):
s = list(input())
while s != ['6', '1', '7', '4']:
s_max = sorted(s, reverse=True)
s_min = sorted(s)
x = int(''.join(s_max))
y = int(''.join(s_min))
그리고 이제 x - y를 해서 나온 값을 다시 리스트에 넣어줘야하는데, 이번에도 숫자 하나하나 떼어서 저장해야하므로 str형으로 바꿔준 후에 리스트로 변환해줍시다.
for i in range(t):
s = list(input())
while s != ['6', '1', '7', '4']:
s_max = sorted(s, reverse=True)
s_min = sorted(s)
x = int(''.join(s_max))
y = int(''.join(s_min))
s = list(str(x-y))
여기서 주의할 점이 하나 있는데요. 만약 1000이라는 입력값이 들어오면 x = 1000이고, y = 0001이라 x - y = 999라는 값이 됩니다. 우리는 계속 4자리로 만들어줘야하므로 len(s) < 4이면 for문을 4 - len(s)동안 돌려서 '0'을 추가하면 됩니다.
이것은 if len(s) < 4를 안하고 for문으로 돌려도 잘 작동합니다. 왜냐하면 len(s) == 4일 때 4 - len(s) = 0이라서 for문이 돌아가지 않고 그대로 통과하게 되거든요.
t = int(input())
for i in range(t):
s = list(input())
while s != ['6', '1', '7', '4']:
s_max = sorted(s, reverse=True)
s_min = sorted(s)
x = int(''.join(s_max))
y = int(''.join(s_min))
s = list(str(x-y))
for j in range(4-len(s)):
s.append('0')
그리고 마지막으로 몇 번의 연산을 해줘야되는지 출력해야하므로 ans 라는 변수를 while문 밖에 만들어주고 while문이 돌아갈 때마다 ans += 1을 해주고 출력해주면 됩니다.
t = int(input())
for i in range(t):
s = list(input())
ans = 0
while s != ['6', '1', '7', '4']:
ans += 1
s_max = sorted(s, reverse=True)
s_min = sorted(s)
x = int(''.join(s_max))
y = int(''.join(s_min))
s = list(str(x-y))
for j in range(4-len(s)):
s.append('0')
print(ans)
4. BOJ 4806 줄 세기
줄의 개수를 세는 문제입니다.
입력값이 주어지지 않았으므로 EOF일 때 입력이 끝납니다.
우리가 EOF 파트에서 배웠던 try / except를 사용하거나 for문과 sys.stdin을 사용하면 됩니다.
저는 try / except문을 사용하겠습니다.
ans = 0
while 1:
try:
ans += 1
input()
except EOFError: break
5. BOJ 17206 준석이의 수학 숙제
3의 배수 또는 7의 배수를 모두 구해서 더한 값을 출력하는 수학 문제입니다.
이 문제는 아마 for문으로 구했으면 시간 초과가 날 것이라고 생각합니다.
일단 입력값을 받는 코드를 짜봅시다. 그리고 for문을 돌려서 arr[i]의 값을 x라고 설정합니다.
t = int(input())
arr = list(map(int,input().split()))
for i in range(t):
x = arr[i]
이제 3의 배수와 7의 배수를 구해야 하는데요. 여기서 우리는 3의 배수를 따로 구해서 더하고, 7의 배수를 따로 구해서 더하는 방법을 생각할 수 있습니다. 이러면 3과 7의 최소공배수인 21의 배수가 두 번 들어가므로 21의 배수도 구해서 더한다음 빼야겠네요.
x = 21일 때를 예시로 들어서 풀어봅시다.
3의 배수 : 3, 6, 9, 12, 15, 18, 21
7의 배수 : 7, 14, 21
21의 배수: 21
이렇게해서 (3의 배수의 합) + (7의 배수의 합) - (21의 배수의 합)을 구하면 답이 나오게 됩니다.
각 숫자의 배수의 합을 어떻게 구할 수 있을까요?
먼저 3의 배수부터 보겠습니다.
3의 배수는 3부터 21까지 총 7개의 숫자가 있습니다. 이것은 21 // 3 = 7과 같습니다.
그리고 3의 배수 숫자를 모두 3으로 나누어보면 1(3), 2(6), 3(9), 4(12), 5(15), 6(18), 7(21)이 나옵니다.
그래서 1 ~ N까지의 합 공식을 적용하여 다 더해주고 그다음 3을 곱해주면 값이 나오게 됩니다.
1 ~ N의 합 공식은 n * (n+1) // 2입니다.
여기서 N = 7이므로 7 * 8 / 2 = 28이 나옵니다. 그리고 3을 곱해주면 84가 나오겠네요.
3 + 6 + 9 + 12 + 15 + 18 + 21 = 84가 나와서 똑같습니다.
7의 배수도 한 번 보겠습니다.
7의 배수는 7, 14, 21 3개로 21 // 7과 값이 같습니다.
이번에도 모든 배수에 7을 나누어줍시다. 그러면 1(7), 2(14), 3(21)이 나오겠네요.
N = 3이므로 1 ~ 3까지의 합은 3 * 4 / 2 = 6이고 여기에 7을 곱하면 42가 나옵니다. 7 + 14 + 21 역시 42가 나옵니다.
21의 배수도 똑같은 방식으로 하면 같다는 것을 알 수 있습니다.
이것을 이제 코드로 만들어 보겠습니다.
t = int(input())
arr = list(map(int,input().split()))
for i in range(t):
x = arr[i]
ans = 0
a = x // 3
먼저 답을 출력할 ans 변수를 하나 만들어주고, a에 x를 3으로 나눈 몫을 넣어줍시다.
그리고 이제 a를 이용하여 1부터 a까지의 합을 구해주어 ans에 더해주면 됩니다.
t = int(input())
arr = list(map(int,input().split()))
for i in range(t):
x = arr[i]
ans = 0
a = x // 3
ans += 3 * (a * (a+1) // 2)
마찬가지로 7의 배수를 구한 값을 모두 더해줘서 ans에 더해주고, 21의 배수는 ans에 빼주면 됩니다.
t = int(input())
arr = list(map(int,input().split()))
for i in range(t):
x = arr[i]
ans = 0
a = x // 3
ans += 3 * (a * (a+1) // 2)
b = x // 7
ans += 7 * (b * (b+1) // 2)
c = x // 21
ans -= 21 * (c * (c+1) // 2)
print(ans)
'Koala - 3기 > 기초 스터디' 카테고리의 다른 글
7주차 복습 문제 해설 (1) | 2021.04.27 |
---|---|
6주차 복습 문제 해설 (0) | 2021.04.20 |
4주차 복습 문제 해설 (0) | 2021.04.06 |
3주차 복습 문제 해설 (0) | 2021.03.30 |
기초 스터디 출석부 (0) | 2021.03.23 |