Pandas나 Numpy를 활용하면 분명 표를 바로 그릴 수 있는 방법이 있겠지만,

이 모듈들은 대부분의 코딩테스트에서는 사용할 수 없으므로 사용하지 않고 구현을 해보기로 했다.

덕분에 내가 아는 방법 내에서는 함수를 사용해서 위의 표를 일일이 경우의 수대로 if문으로 만들어서 리턴시키는 방법뿐이었다.

 

다음의 코드대로 했더니 문제를 맞힐 수 있었다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
def dnaTable(col, row):
    if col == 'A' and row == 'A':
        return 'A'
    if col == 'A' and row == 'G':
        return 'C'
    if col == 'A' and row == 'C':
        return 'A'
    if col == 'A' and row == 'T':
        return 'G'
 
    if col == 'G' and row == 'A':
        return 'C'
    if col == 'G' and row == 'G':
        return 'G'
    if col == 'G' and row == 'C':
        return 'T'
    if col == 'G' and row == 'T':
        return 'A'
 
    if col == 'C' and row == 'A':
        return 'A'
    if col == 'C' and row == 'G':
        return 'T'
    if col == 'C' and row == 'C':
        return 'C'
    if col == 'C' and row == 'T':
        return 'G'
 
    if col == 'T' and row == 'A':
        return 'G'
    if col == 'T' and row == 'G':
        return 'A'
    if col == 'T' and row == 'C':
        return 'G'
    if col == 'T' and row == 'T':
        return 'T'
 
num = int(input())
dnaCode = list(map(str, input()))
= 0
while(i != num):
    i += 1
    decode = []
    decode.append(dnaTable(dnaCode[num-i], dnaCode[num-i-1]))
    # print(dnaCode)
    if len(dnaCode) != 1#dnaCode가 비어있지 않으면
        dnaCode.pop()
        dnaCode.pop()
        dnaCode.append(decode[0])
    else:
        break
print(dnaCode[0])
 
cs

 

이게 맞나 싶을 정도로 함수 부분의 코드가 길어진 부분에 대해서 끊임없이 의심하면서도 결국 노가다성의 코드를 만들었다.

밑의 코드에서는 while문을 활용해서 decode에 계속 해독된 코드 부분을 집어넣고

dnaCode에서 해독해야 할 부분의 2 문자를 빼서 해독된 부분을 새로 추가시켜주는 방법이다.

이때, dnaCode에 우리가 원하는 최종 문자 1개가 남았을 경우, while문에서 break 하고,

해당 문자를 출력해주기만 하면 된다.

 

사실 언뜻 보기만 해도 꽤나 지저분한 코드라고 스스로도 생각하고 있다.

뭔가 더 깔끔한 방법의 코드가 있다면.. 혹은 조언을 받을 수 있다면, 추후에 다시 이 해당 문제를 수정해볼 생각이다...

 

 

문제 출처: https://www.acmicpc.net/problem/1672

 

1672번: DNA 해독

N개의 A, G, C, T로 구성되어 있는 DNA 염기서열이 있다. 그리고 우리는 이 염기서열을 아래의 표를 이용하여 해독을 해야 한다. 해독 방법은 염기 서열에서 제일 끝에 있는 두 개의 염기를 An-1, An이

www.acmicpc.net


해당 문제에 대해서 다음의 코드가 첫 번째 시도였고, 시간 초과라는 문제가 계속 발생했다.

1
2
3
4
5
6
7
import sys
a, b = map(str, sys.stdin.readline().split())
total = []
for i in a:
    for j in b:
        total.append(int(i)*int(j))
print(sum(total))
cs

 


그래서 계속 문제를 보던 중, 반복문을 사용하지 않고 하는 방법이 있던 것을 발견했다.

이 부분은 코드의 문제라기보다는 수학 문제에 가깝다고 봐야 할 듯하다.

 

1*3 + 1*4 + 2*3 + 2*4 + 1*3 + 1*4 = 28

==>이 식을 더욱 간단한 식으로 바꾸면...

 

(1 + 2 + 1) * (3 + 4)

라는 식이 나온다는 점을 찾아야 한다.

 

(A + B) * (C + D) = AC + AD + BC + BD라는 형태의 식을 생각하면 금방 답이 나올 것이다...

 

따라서, 다음과 같은 코드를 해야 제대로 시간 초과 없이 문제를 맞힐 수 있다.

1
2
3
4
5
6
a, b = input().split()
 
= list(map(int, a))
= list(map(int, b))
print(sum(a) * sum(b))
 
cs

 

 

문제 출처: https://www.acmicpc.net/problem/1225

 

1225번: 이상한 곱셈

첫째 줄에 A와 B가 주어진다. 주어지는 두 수는 모두 10,000자리를 넘지 않는다.

www.acmicpc.net


부끄럽게도 정답률이 꽤 높은 문제임에도 불구하고 시간이 꽤 걸렸던 문제이다.

90이라는 max 값을 구하기는 상당히 쉬운데, 행열을 출력하는 부분 때문에 조금 난항을 겪었다.

다음 코드처럼 나는 작성했더니 결과가 잘 나왔다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import sys
arr = []
maxN = [0]
for i in range(9):
    arr.append(list(map(int, sys.stdin.readline().split())))
for i in range(9):
    for j in range(9):
        if max(arr[i]) == arr[i][j] and max(arr[i])>=maxN[0]:
            maxN.pop()
            maxN.append(arr[i][j])
            i_num = i
            j_num = j
        else:
            pass
print(maxN[0])
print(i_num+1, j_num+1)
cs

 

딱 봐도 자랑스럽게 내세울만한 코드는 아니다... 오히려 지저분한 코드라는 생각이 확실히 들긴 한다.

 

리스트를 꽤 많이 사용했다. 

도저히 어떻게 list에 값을 넣지 않고 처리를 해야 할지 생각이 안 나서 저렇게 maxN처럼 전역변수처럼 리스트를 처리해서 해당 값을 이중 for문 내에 있는 if문의 조건에 따라 업데이트시키는(line 8~) 방법을 사용했다.

 

그리고 딱 봐도 for문에 이중for문까지 있어서 시간 복잡도가 O(n^2)이 나와서 시간 초과가 될 것 같았다.

그래서 line 4에서와 같이 input()을 사용하지 않고 sys.stdin.readline()를 사용해서 처리했다.

그렇게 처리할 경우, 다음과 같은 실행시간이 나와서 잘 처리가 되었다.

해당 코드의 실행시간

추후에 다시 이 코드로 돌아와서 조금 더 깔끔한 코드를 손봐줄 필요성이 강하게 느껴진다...

 

 

문제 출처: https://www.acmicpc.net/problem/2566

 

2566번: 최댓값

첫째 줄에 최댓값을 출력하고, 둘째 줄에 최댓값이 위치한 행 번호와 열 번호를 빈칸을 사이에 두고 차례로 출력한다. 최댓값이 두 개 이상인 경우 그 중 한 곳의 위치를 출력한다.

www.acmicpc.net


일단 조금 고생을 해서 slicing을 통해서 나는 문제를 해결하였다.

다음의 코드로 돌렸을 때 맞기는 했다.

1
2
3
4
5
6
7
8
9
10
num = input()
# print(num[len(num)-2:len(num)])
if int(num[len(num)-2:len(num)]) <= 10:
    if num[len(num)-2:len(num)-1== '0':
        print(int(num[0:len(num)-2])*10+ int(num[len(num)-1:len(num)]))
    else:
        print(int(num[0:len(num)-2]) + int(num[len(num)-2:len(num)]))
else:
    print(int(num[0:len(num)-1]) + int(num[len(num)-1:len(num)]))
 
cs

다만, 코드가 사실 무적이나 더럽(?)다라는 생각이 들기는 한다...

분명히 더 아름다운 코드를 짤 수는 있겠지만.. 일단 당장은 저런 식으로 풀 수 있다는 것으로 만족하고,

추후에 조금 더 공부를 하고, 조금 더 좋은 아이디어가 생기면 다시 풀어볼 생각이다.

 

 

문제 출처: https://www.acmicpc.net/problem/15873

 

15873번: 공백 없는 A+B

자연수 A, B (0 < A, B ≤ 10)가 첫 번째 줄에 주어진다. 단, 두 수의 사이에는 공백이 주어지지 않는다. 두 수의 앞에 불필요한 0이 붙는 경우는 없다.

www.acmicpc.net

 


list(map(int, input().split()))을 잘 사용해서,

조건식에 맞게 잘 출력되도록 처리만 하면 되는 간단한 문제이다.

 

1
2
3
4
5
6
= sum(list(map(int, input().split())))
= sum(list(map(int, input().split())))
if a >= b:
    print(a)
else:
    print(b)
cs

 

문제 출처: https://www.acmicpc.net/problem/5596

 

5596번: 시험 점수

대한고등학교에 재학 중인 민국이와 만세는 4과목(정보, 수학, 과학, 영어)에 대한 시험을 봤다. 민국이와 만세가 본 4과목의 점수를 입력하면, 민국이의 총점 S와 만세의 총점 T 중에서 큰 점수

www.acmicpc.net

 


간단하게 int로 input을 받은 후,

결과값을 17배 시키고,

이를 이진수로 바꾸기 위해서 bin을 하용합니다.

1
2
3
4
5
N = int(input(), 2)
 
result = N * 17
 
print(bin(result)[2:])
cs

 

 

출처: https://www.acmicpc.net/problem/5893

 

5893번: 17배

첫째 줄에 이진수 N이 주어진다. N은 최대 1000자리인 이진수이며, 0이 들어오는 경우는 없다.

www.acmicpc.net


코드가 조금 길고 조잡하긴 하지만....

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import sys
exist = []
cnt = 0
for i in range(8):
    exist.append(sys.stdin.readline())
    if i % 2 == 0:
        j = 0
        for j in range(8):
            if j % 2 == 0:
                if exist[i][j] == 'F':
                    cnt += 1
                    j += 1
    else:
        j = 0
        for j in range(8):
            if j % 2 == 1:
                if exist[i][j] == 'F':
                    cnt += 1
                    j += 1
print(cnt)
 
cs

이런 식으로 나는 일단 첫 번째 try에서 문제를 해결했다.

다만, 시간이 84ms로 조금은 느린 시간대를 가졌다.

당연히, 그럴 수밖에 없는 것은, 이중 for문에 의해서 반복이 여러 번 돌아야 하고, if문도 여러 개 있어서 각각에 대한 조건을 찾는 데 있어서 시간이 걸리기 때문이다.


이를 조금 해결할 수 있는 부분은 다음의 코드처럼 range()의 값에 조건을 주면 된다.

1
2
3
4
5
6
7
8
9
10
11
12
count = 0
for i in range(1,9):
    n = input()
    if i % 2 == 1
        for k in range(0,7,2):
            if n[k] == 'F':
                count += 1
    else:
        for k in range(1,8,2):
            if n[k] == 'F':
                count += 1
print(count)
cs

이렇게 range()에 건너뛰기의 조건을 주게 되면, 별도로 j라는 변수를 만들지 않아도 되며, if 조건문도 줄일 수 있게 된다.

실행시간 또한 68ms 정도로 확 줄어드는 것을 볼 수 있게 된다.

 

 

 

문제 출처: https://www.acmicpc.net/problem/1100

 

1100번: 하얀 칸

체스판은 8*8크기이고, 검정 칸과 하얀 칸이 번갈아가면서 색칠되어 있다. 가장 왼쪽 위칸 (0,0)은 하얀색이다. 체스판의 상태가 주어졌을 때, 하얀 칸 위에 말이 몇 개 있는지 출력하는 프로그램

www.acmicpc.net


친절하게 힌트까지 있는 문제이다.

일단 문제는 굉장히 간단한데 문제는 백준의 시간 초과이다.

이전에 올린 문제 (https://gettingtoknowit.tistory.com/99)와 같이 sys를 사용해야 시간 초과가 걸리지 않는다.

 

[백준] 10828_스택 파이썬

우선 간단히 스택 구조에 대해서 정리해보자면, 스택(stack)은 LIFO(Last In First Out) 구조이다. 즉, 가장 최근에 스택에 추가한 항목이 가장 먼저 나오는 항목이 된다. 아마 C/C++로 했으면 코드가 길어

gettingtoknowit.tistory.com


코드는 다음과 같이 하면 되지만, 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import sys
= int(sys.stdin.readline())
num_list = []
for _ in range(k):
    num = int(sys.stdin.readline())
    if num != 0:
        num_list.append(num)
    else:
        num_list.pop()
 
total = 0
for i in num_list:
    total += i
print(total)
cs

 

위의 코드를 sum으로 더 간단하게 만드는 것 또한 가능하다.

1
2
3
4
5
6
7
8
9
import sys
= int(sys.stdin.readline())
num_list = []
for _ in range(k):
    num = int(sys.stdin.readline())
    if num != 0:
        num_list.append(num)
    else:
        num_list.pop()
print(sum(num_list))
cs

 

 

문제 출처: https://www.acmicpc.net/problem/10773

 

10773번: 제로

첫 번째 줄에 정수 K가 주어진다. (1 ≤ K ≤ 100,000) 이후 K개의 줄에 정수가 1개씩 주어진다. 정수는 0에서 1,000,000 사이의 값을 가지며, 정수가 "0" 일 경우에는 가장 최근에 쓴 수를 지우고, 아닐 경

www.acmicpc.net


우선 간단히 스택 구조에 대해서 정리해보자면, 스택(stack)은 LIFO(Last In First Out) 구조이다. 즉, 가장 최근에 스택에 추가한 항목이 가장 먼저 나오는 항목이 된다.

이미지 출처: https://www.programiz.com/dsa/stack

 

아마 C/C++로 했으면 코드가 길어지고 조금은 어려웠을지도 모르겠다고 느껴지겠지만,

확실히 파이썬으로 하니 간단하게 처리할 수 있었다.

파이썬에서는 C++처럼 스택에 대한 STL은 없지만, list의 append, pop 메서드를 활용하여 간단하게 처리할 수 있다.

 

자세한 부분은 https://docs.python.org/ko/3/tutorial/datastructures.html를 참고하면 된다.

 

5. 자료 구조 — Python 3.9.6 문서

5. 자료 구조 이 장에서는 여러분이 이미 배운 것들을 좀 더 자세히 설명하고, 몇 가지 새로운 것들을 덧붙입니다. 5.1. 리스트 더 보기 리스트 자료 형은 몇 가지 메서드들을 더 갖고 있습니다. 이

docs.python.org


대신 백준에서 파이썬 코드를 제출할 때, input()을 활용하면 시간 초과가 뜬다. 

다라서, sys.stdin.readline()을 사용해야 한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import sys
num = int(sys.stdin.readline())
stack = []
= 0
for i in range(num):
    stack_word = sys.stdin.readline()
    if stack_word[:4== "push":
        stack.append(int(stack_word[5:]))
    if stack_word[:3== "pop":
        if len(stack) != 0:
            print(stack.pop())
        else:
            print(len(stack) - 1)
    elif stack_word[:4== "size":
        print(len(stack))
    elif stack_word[:5== "empty":
        if len(stack) == 0:
            print(1)
        else:
            print(0)
    elif stack_word[:3== "top":
        if len(stack) == 0:
            print(-1)
        else:
            print(stack[-1])
    else:
        pass
    i += 1
 
cs

 

 

문제 출처: https://www.acmicpc.net/problem/10828

 

10828번: 스택

첫째 줄에 주어지는 명령의 수 N (1 ≤ N ≤ 10,000)이 주어진다. 둘째 줄부터 N개의 줄에는 명령이 하나씩 주어진다. 주어지는 정수는 1보다 크거나 같고, 100,000보다 작거나 같다. 문제에 나와있지

www.acmicpc.net


생각보다 시간을 썼던 문제이지만, 논리만 잘 세우면 금방 해결할 수 있는 문제이다.

첫 번째 for문에서 member_list.append만 제대로 해주면 된다. 

 

그리고 lambda를 잘 사용해서 정렬 처리를 하는 게 또 다른 핵심이라고 보면 될 듯하다.

1
2
3
4
5
6
7
8
9
10
11
12
num = int(input())
member_list = []
for _ in range(num):
    age, name = map(str, input().split())
    age = int(age)
    member_list.append((age, name))
# print(member_list)
# 나이가 같으면 먼저 가입한 사람이 앞에 오는 순서
member_list.sort(key = lambda x: x[0])
# print(member_list)
for i in member_list:
    print(i[0], i[1])
cs

 

 

문제 출처: https://www.acmicpc.net/problem/10814

 

10814번: 나이순 정렬

온라인 저지에 가입한 사람들의 나이와 이름이 가입한 순서대로 주어진다. 이때, 회원들을 나이가 증가하는 순으로, 나이가 같으면 먼저 가입한 사람이 앞에 오는 순서로 정렬하는 프로그램을

www.acmicpc.net

+ Recent posts