문제를 잘 읽고 개념만 잘 익히면 대부분의 문제를 다 풀 수 있을 정도의 난이도였지만
사소한 거 하나를 빠뜨려 오래 걸렸던 문제, 개념이 잘 잡혀있지 않았던 문제 위주로 블로깅함.
81번
A, B, C, D, E, F 중 하나가 입력될 때,
1부터 F까지 곱한 16진수 구구단의 내용을 출력해보자.
(단, A ~ F 까지만 입력된다.)
입력
16진수로 한 자리 수가 입력된다.단, A ~ F 까지만 입력된다.
출력
입력된 16진수에 1~F까지 순서대로 곱한, 16진수 구구단을 줄을 바꿔 출력한다.계산 결과도 16진수로 출력해야 한다.
Logic
1. 16진수로 한 자리 수를 입력받는다.2. 입력된 16진수에 1~F까지 순서대로 곱하고 줄을 바꿔 출력한다.3. 계산 결과도 16진수로 출력해야함.
사실 이 문제는 알고보면 전혀 어려운 문제가 아닌데처음 문제를 읽고 16진수라고 하니까 어렵게 생각한게 문제였다.
사실 저번 학기때 16진수를 친구한테 맞으면서 배웠다^^
내가 제시한 오답 코드
n = int(input(), 16)
for i in range(1, 16):
a = hex(i)
print("%X"%n, "*%X"%i, "=%X"%(n*a), sep='')
입력 :
B
출력 결과 :
< 아무것도 안나옴 >
정말 수치스러운 결과..
이때, 무슨 생각으로 저런 코드를 짰냐면
16진수끼리 곱해야되는 줄 알았다, 그래서 i 를 16진수로 바꿔서 그걸 곱했는데
이게 16진수도 결국 그냥 수를 0 .. 9 A B C D .. F 로 표현한것인데
그냥 계산하고 출력만 16진수로 했으면 됐었다
내가 제시한 정답 코드
n = int(input(), 16)
for i in range(1, 16):
print('%X'%n, '*%X'%i, '=%X'%(n*i), sep='')
16진수로 입력을 받고, i 가 순서대로 1 부터 15까지 증가하는 for 문을 이용하여 구구단을 출력했다.
이때, sep='' 는 출력 문자들 간의 공백이 없게 출력하게 해준다.
82번
문제 : 친구들과 함께 3 6 9 게임을 하던 영일이는 잦은 실수 때문에 계속해서 벌칙을 받게 되었다.
3 6 9 게임의 왕이 되기 위한 369 마스터 프로그램을 작성해 보자.
입력
30보다 작은 정수 1개가 입력된다. (1 ~ 29)
출력
1부터 그 수까지 순서대로 공백을 두고 수를 출력하는데,
3 또는 6 또는 9가 포함 되어있는 수인 경우, 그 수 대신 영문 대문자 X 를 출력한다.
Logic
1. 30보다 작은 정수 1개를 입력 받는다.
2. 1부터 입력 받은 수까지 공백을 두고 수를 출력한다.
3. 조건 : 3 or 6 or 9 가 포함되어 있는 수이면 X 를 출력한다.
내가 제시한 오답 코드 1
n = int(input()) // 1 ~ 29 사이의 정수를 입력받음.
for i in range(1, 30):
print(i, end='')
if i%10 == 3 or i%10 == 6 or i%10 == 9:
print("X", end='')
입력 :
9
123X456X789X10111213X141516X171819X20212223X242526X272829X
엄청 엉망진창으로 풀었음 ㅎㅎ.. 졸면서 풀었나..
1. 1부터 입력 받은 수까지 증가하는 것인데 for i in range(1, 30) 으로 입력한게 첫번째 오답의 이유
2. 공백을 두고 출력해야하는데 end='' 라고 한 것이 두번째 오답의 이유
3. 반복실행문과 조건문 로직 자체의 오류.
코드를 짤 때 이대로 가면 실행 과정이 어떤 식으로 진행되는지 분석을 해야하는데 그것이 부족했음.
123X456X ... 로 나오는 이유는 print 문이 조건문에 앞서서 순서대로 실행되는 걸 간과했음.
내가 제시한 오답 코드 2
n = int(input())
for i in range(1, n+1):
if i%10 == 3:
print("X", end=' ')
elif i%10 == 6:
print("X", end=' ')
elif i%10 == 9:
print("X", end=' ')
print(i, end=' ')
입력 :
9
1 2 X 3 4 5 X 6 7 8 X 9
내가 제시한 오답 코드 1 과 마찬가지로 로직을 잘못 짰는데 정답과 거의 가까워졌음.
1. 앞선 것과 마찬가지로 3, 6, 9를 출력하지 않아야하는데 X 를 먼저 출력하고 3, 6, 9를 그대로 출력한 것이 오답의 이유.
이때, else 가 빠졌다는 것을 인지함. 저 3개의 케이스에 해당되지 않는 나머지 숫자들은 저 조건문을 거치고 그냥 출력될 것이고, 3개의 케이스에 해당이 되면 if 문 안의 실행 코드만 실행하고 넘어가야하는데 else 문이 없으니 그냥 그대로 출력한 거였음.
내가 제시한 정답 코드 1
n = int(input())
for i in range(1, n+1):
if i%10 == 3:
print("X", end=' ')
elif i%10 == 6:
print("X", end=' ')
elif i%10 == 9:
print("X", end=' ')
else:
print(i, end=' ')
결국 else 문을 삽입하고 성공했음. 하지만 이것보다 더 짧은 코드를 짤 수 있지 않을까? 생각이 들었음.
사실 이렇게 블로깅하다가 첫번째로 제시했던 오답 코드로 더 짧게 작성할 수 있을 거 같아서 다시 짜봤음.
내가 제시한 정답 코드 2
n = int(input())
for i in range(1, n+1):
if i%10 == 3 or i%10 == 6 or i%10 == 9:
print("X", end=' ')
else:
print(i, end=' ')
코드 길이, 실행 시간 다 짧아졌당 ㅎㅎ
90번
문제 : 시작 값(a), 곱할 값(m), 더할 값(d), 몇 번째인지를 나타내는 정수(n)가 입력될 때,
n번째 수를 출력하는 프로그램을 만들어보자.
입력
시작 값(a), 곱할 값(m), 더할 값(d), 몇 번째 인지를 나타내는 정수(n)가
공백을 두고 입력된다.(a, m, d는 -50 ~ +50, n은 10이하의 자연수)
출력
n번째 수를 출력한다.
Logic
1. a, m, d, n 을 공백을 두고 입력 받는다.
2. 시작값에 m 을 곱하고 d 를 더한 후 n 번째 수를 출력한다.
3. 이때, 시작값이 a1, a2, a3 ... 로 바뀐다는 것을 생각해야한다.
내가 제시한 오답 코드
a, m, d, n = input().split()
a = int(a)
m = int(m)
d = int(d)
n = int(n)
for i in range(1, n+1):
a = a * m + d
print(a)
입력 :
1 -2 1 8
출력 결과 :
171
정답이 -85가 나와야하는데 왜 171이 나왔는지 한번 출력을 해봤다.
-1
3
-5
11
-21
43
-85
171
출력 결과를 보니 8번째 수가 171이다. 정답은 그 전의 항 -85가 나와야한다. 왜 이런식으로 되었을까?
여기서 첫번째 항이 이상했다. 시작값은 1이 되어야하는데 -1이 되었다. 1 * -2 + 1 = -1, 첫번째 항이 계산 후 결과가 되어버린것이다.
그렇다면 첫째항은 계산하지 않은 첫째항 그대로 두는 조건을 넣으면 되지 않을까?
내가 제시한 정답 코드
a, m, d, n = input().split()
a = int(a)
m = int(m)
d = int(d)
n = int(n)
for i in range(1, n+1):
if i == 1:
a = a
else:
a = a * m + d
print(a)
첫째항을 시작값으로 그대로 두고
그 이후에는 계산한 값을 순서대로 2번째, 3번째, 4번째... 로 두는 코드로 작성했다!
94번
문제 : 정보 선생님은 오늘도 이상한 출석을 부른다.
영일이는 오늘도 다른 생각을 해보았다.
출석 번호를 다 부르지는 않은 것 같은데... 가장 빠른 번호가 뭐였지?
출석 번호를 n번 무작위로 불렀을 때, 가장 빠른 번호를 출력해 보자.
단, 첫 번째 번호와 마지막 번호가 몇 번인지는 아무도 모른다.
음수(-) 번호, 0번 번호도 있을 수 있다.
입력
번호를 부른 횟수(n, 1 ~ 10000)가 첫 줄에 입력된다.
n개의 랜덤 번호(k)가 두 번째 줄에 공백을 사이에 두고 순서대로 입력된다.
출력
출석을 부른 번호 중에 가장 빠른 번호를 출력한다.
Logic
1. 번호를 부른 횟수 n 을 정수형으로 입력 받는다.
2. n 개의 랜덤 번호 k 가 공백을 사이에 두고 순서대로 입력된다.
3. 제일 작은 수는 예측할 수 없으므로(음수일수도 있다고 문제에서 제시함.) 입력 받은 값을 비교 대상으로 만들어야 한다.
이 문제는 정답 코드를 보면 크게 어려운 문제는 아니지만
처음 문제를 보았을 때 어떻게 풀어야하나 고민을 많이 했던 문제라 넣었다.
내가 제시한 오답 코드
n = int(input())
a = list(map(int, input().split))
for i in range(n):
if a[i] < a[i+1]:
min = a[i]
elif i == n-1:
print(min)
break
else:
continue
랜덤 번호를 a 리스트에 띄어쓰기 기준으로 넣어놓고
for 문을 돌려서 a 리스트 안에 존재하는 값들끼리 비교하는 것을 넣었다.
이때, 0 ~ n-1 까지 for 문을 돌렸는데 두 값끼리 비교해서 작은 것은 min 에 대입하고 i 가 n-1 까지인데 이때 첫번째 if 문에서 a[n-1] < a[n] 이 될 수 없기 때문에 elif 문을 넣었는데 사실 무슨 생각으로 저렇게 짰는지 모르겠다..ㅎㅎ
내가 제시한 정답 코드
n = int(input())
k = list(map(int, input().split()))
for i in range(n):
if k[i] <= k[0]:
k[0] = k[i]
else:
continue
print(k[0])
조금 더 간단하게 생각해보자! 라는 생각으로
맨 처음 원소를 기준으로 비교하면서 작으면 계속 맨 처음 원소로 넣어버리자! 라고 결론을 내렸다.
그렇게 생각하니 코드를 좀 더 쉽게 짤 수 있었다.
처음 원소보다 비교하는 원소가 작거나 같아버리면 처음 원소에 대입해버리고 만약 그렇지 않으면 쭉 n-1 까지 진행하는 것으로 짰다.
그러면 저 반복문이 끝났을 때 맨 처음 원소에 제일 작은 숫자가 올 것이고 따라서 제일 처음 원소를 출력하면 끝나는 것이다.
96번
문제 : 십자 뒤집기는
그 위치에 있는 모든 가로줄 돌의 색을 반대(1->0, 0->1)로 바꾼 후,
다시 그 위치에 있는 모든 세로줄 돌의 색을 반대로 바꾸는 것이다.
어떤 위치를 골라 집자 뒤집기를 하면, 그 위치를 제외한 가로줄과 세로줄의 색이 모두 반대로 바뀐다.
바둑판(19 * 19)에 흰 돌(1) 또는 검정 돌(0)이 모두 꽉 채워져 놓여있을 때,
n개의 좌표를 입력받아 십(+)자 뒤집기한 결과를 출력하는 프로그램을 작성해보자.
입력
바둑알이 깔려 있는 상황이 19 * 19 크기의 정수값으로 입력된다.
십자 뒤집기 횟수(n)가 입력된다.
십자 뒤집기 좌표가 횟수(n) 만큼 입력된다. 단, n은 10이하의 자연수이다.
출력
십자 뒤집기 결과를 출력한다.
Logic
1. 19 * 19 크기의 2차원 리스트를 입력받는다.
2. 십자 뒤집기 횟수 n 을 입력 받는다.
3. 십자 뒤집기 좌표 x, y 를 입력받고 해당되는 좌표의 바둑돌을 0->1, 1->0 으로 변경한다.
정말 역대급으로 오래 걸렸던 문제였다..전부터 항상 배열에 약했는데 공부의 필요성을 절실하게 깨닫게 해준 문제였다.. ㅎㅎ
해당되는 좌표의 바둑돌을 0->1, 1->0 으로 바꾸는 것도 어려웠지만 문제에서 이미 힌트를 주었고
처음부터 19*19 크기의 2차원 리스트를 입력받는 것이 난관이였다.
내가 제시한 오답 코드
d = [list(map(int, input().split())) for i in range(1,20)]
for i in range(n):
x,y=input().split()
for j in range(1, 20) :
if d[j][int(y)]==0 :
d[j][int(y)]=1
else :
d[j][int(y)]=0
if d[int(x)][j]==0 :
d[int(x)][j]=1
else :
d[int(x)][j]=0
for i in range(1, 20):
for j in range(1, 20):
print(d[i][j], end=' ')
print()
2차원 리스트를 출력하는 건 이중 for 문을 돌리면 된다는 것을 알고 있었기 때문에 출력은 어렵지 않았다.
하지만 처음 입력을 받는 것을 어떻게 해야할지 복잡했다.
이것도 이중 for 문을 돌려야하나? 미리 2중 리스트를 만들고 0 이라는 값을 모두 대입한 다음 입력을 받아야하나 그럼 이때 입력 받는 것도 이중 for 문인가? 하면서 머리가 실타래처럼 꼬였다..
내가 제시한 정답 코드
d=[]
for i in range(20):
d.append([])
for j in range(20):
d[i].append(0)
for i in range(19):
a = input().split()
for j in range(19):
d[i+1][j+1] = int(a[j])
n = int(input())
for i in range(n):
x,y=input().split()
for j in range(1, 20):
if d[j][int(y)]==0:
d[j][int(y)]=1
else :
d[j][int(y)]=0
if d[int(x)][j]==0:
d[int(x)][j]=1
else :
d[int(x)][j]=0
for i in range(1, 20):
for j in range(1, 20):
print(d[i][j], end=' ')
print()
그래서 차근 차근 적어가면서 해보았다.
첫번째, d 라는 빈 리스트를 선언 후에 앞선 문제처럼 리스트 안에 리스트를 추가하였다.
그리고나서 두번째, 입력을 받는다. 이때 입력은 한 줄씩 입력받아서 넣는 것으로 했다.
우선, 첫번째 행에 띄어 쓰기 기준으로 a 라는 리스트에 대입하고, 이를 for 문을 돌려서 1행부터 19행까지 왼쪽에서 오른쪽으로 차근 차근 값을 대입하는 것으로 했다.
풀린 순간 정말 세상이 아름다워보였다.. 이 맛에 코딩을 하나보다..
<파이썬 코드업 기초 100제 올클리어 인증>
'TeamH4C' 카테고리의 다른 글
[빡공팟 5기] W4 : Web Hacking 로드맵 - STAGE 1 - 1 (0) | 2022.10.12 |
---|---|
[빡공팟 5기] W4 : Mac OS 에서 Burp Suite 설치 및 기본 기능 이해 (0) | 2022.10.12 |
[빡공팟 5기] W1 ~ W3 : 웹 사이트 구현 완성 (0) | 2022.10.09 |
[빡공팟 5기] W1 ~ W3 : 초기 화면 구성 및 DB 연결 (0) | 2022.10.04 |
[빡공팟 5기] W1 ~ W3 : 웹 사이트 구현 초기 설정 (1) | 2022.09.30 |