새벽에 빠르고 가볍게 하나만 풀고 자자는 마인드로 시도를 했지만, 바보같이 엄청 오래 걸린 문제...

심지어 런타임 에러로 인해 고생하다가 포기하고 그냥 검색을 했더니 set() 함수를 사용하면 중복제거를 바로 시켜버리더라... ㅠㅠ

 

일단 런타임 에러가 걸린 코드는 다음과 같다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#runtime error(IndexError)
index = [0]*10
for i in range(10):
    num = int(input())
    index[i] = num % 42
index.sort()
# print(index, end = ' ')
 
cnt = 0
dif = 0
for i in index:
    if index[cnt] == index[cnt+1and cnt != 10:
        index.remove(i)
        cnt += 1
    elif cnt != 0 and index[cnt-1!= index[cnt]:
        cnt += 1
if len(index) == 5:  # 5인 이유는 위의 for문에 의해 모두가 같은 숫자일 때 5개가 남기 때문이다.
    print(1)
else:
    # print(index)
    print(len(index))
 
cs

일단 출력 예제는 pycharm상으로는 잘 돌아가기는 한다.

물론, 입출력 예제가 나오도록 끼워맞춘 코드인지라... 게다가 런타임 에러(IndexError)가 뜨는 걸 보니...

for문에서 index에 문제가 있다는 거다.

저걸 고쳐보려다가... 새벽 2시가 넘어서 도저히 못 건드리겠어서 포기했다...

그리고 검색을 해봤는데......


1
2
3
4
5
6
7
8
9
# 중복제거를 해주는 파이썬의 함수가 존재한다 ==> set()
 
arr = []
for i in range(10):
    n = int(input())
    arr.append(n % 42)
arr = set(arr)
print(len(arr))
 
cs

바로 나와주시는 set() 함수  ㅠㅠㅠㅠ

set( ) 함수로 중복제거를 한 방에 처리해버린다. 굳이 for문까지도 필요가 없다.

 

이전에 올렸던 10809문제에서도 그랬지만... 역시 함수를 알아야 한다.

그래도 궁금해지니 추후에 set( )함수의 실제 소스코드를 한 번 찾아볼 생각이다.

 

 

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

 

3052번: 나머지

각 수를 42로 나눈 나머지는 39, 40, 41, 0, 1, 2, 40, 41, 0, 1이다. 서로 다른 값은 6개가 있다.

www.acmicpc.net

 

원래의 문제는 다음과 같다

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

 

[백준] 10809_알파벳 찾기 파이썬 (복잡하게 푼 방식과 초간단하게 푸는 방법_feat.find(), index(), chr(),

우선 내가 푼 코드부터 올리자면 다음과 같다. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 word = list(input()) alphabet = "abcdefghijklmnopqrstuvwxyz" index = [] for i in range(..

gettingtoknowit.tistory.com

https://gettingtoknowit.tistory.com/78

 

[백준] 10809_알파벳 찾기 파이썬 (복잡하게 푼 방식과 초간단하게 푸는 방법_feat.find(), index(), chr(),

우선 내가 푼 코드부터 올리자면 다음과 같다. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 word = list(input()) alphabet = "abcdefghijklmnopqrstuvwxyz" index = [] for i in range(..

gettingtoknowit.tistory.com


나는 여기서 한 번 알파벳 개수들을 찍어보기로 했다.

그냥 간단하게 말해서, 원래 문제에서는 알파벳의 위치를 출력시켰다고 하면,

나는 입력 문자에 들어있는 알파벳들의 개수를 출력시킨 것이다.

대신, 배열의 초기값을 0으로 시켜서 0개라는 의미를 살려보았다.

코드는 다음과 같이 나왔다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
word = list(input())
 
alphabet = "abcdefghijklmnopqrstuvwxyz"
index = []
for i in range(len(list(alphabet))):
    index.append(0)
 
#알파벳에 따라서 인덱스 값 할당
for i in word:  #baek
    cnt = 0
    for j in list(alphabet):
        if i == j:
            index[cnt] += 1
        cnt += 1
 
for i in range(len(list(alphabet))):
    print(index[i], end = ' ')
 
cs

그리고 다음과 같은 결과 예시가 나온다.

 


우선 내가 푼 코드부터 올리자면 다음과 같다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
word = list(input())
alphabet = "abcdefghijklmnopqrstuvwxyz"
index = []
for i in range(len(list(alphabet))):
    index.append(-1)
 
pos = 0
#알파벳 위치 찾기
for i in word:  #baek
    cnt = 0
    for j in list(alphabet):
        if j == i and index[cnt] != -1:
            pos += 1
            pass
        elif j == i:
            index[cnt] = pos
            pos += 1
        cnt += 1
 
for i in range(len(list(alphabet))):
    print(index[i], end = ' ')
 
cs

내가 한 방식은 조금 무식하게 다 비교하는 방식이다.

1) 우선 리스트로 단어를 입력받는다.

2) index라는 리스트를 생성하고 a~z의 방을 생성하고 안에 -1로 초기화한다

3) pos라는 위치를 저장할 변수를 하나 생성하고 0으로 초기화한다.(position)

4) 이제 단어로 for문을 돌리는데, 이렇게 되면 입력받은 단어를 하나하나 뽑아서 다음 for문의 알파벳 26개와 비교를 하게 된다.

5) 비교를 통해서 만약 index가 -1(=초기값)이 아니고, 알파벳 변수에 있는 알파펫과 같은 알파벳이라면, pos(위치값)를 1 올리는 대신, pass를 시킨다. 이렇게 하는 이유는 중복되는 알파벳은 가장 처음에 나타난 위치를 업데이트시키지 않기 위해서이다.

6) 만약 처음 나타나는 알파벳이라면, 해당 알파벳의 index에 pos(위치값)을 넣어주고, 다음 pos를 위해서 pos +=1을 시킨다.

 

이런 식으로 일일이 비교하게끔 노가다 작업을 프로그램을 통해 하게 된다.


그런데 이걸 풀고 나서 다른사람들의 코드를 리뷰해보니 허탈한 심정이더라...

이유는 다음 코드를 보면 알게 될 것이다.

1
2
3
= input()
for x in range(97123):
    print(a.find(chr(x)), end=" ")
cs

이렇게 보면 알 수 잇듯이 단 3줄로 끝나버린다.

이유는 아스키코드 변환함수인 chr()와 문자열에서만 사용이 가능한 find() 함수를 사용하기 때문이다.

**chr( ) 함수는 숫자(아스키코드) -> 문자로 변환하는 함수

**ord( ) 함수는 문자 -> 숫자(아스키코드)로 변환하는 함수

**find( ) 함수는 괄호 안의 문자가 위치한 자리를 출력한다. (참고로, index( ) 함수도 괄호 안의 문자가 위치한 자리를 출력한다. 다만, find()에서는 찾는 문자가 없는 경우 -1을 출력하는 바면, index()는 찾는 문자가 없는 경우 ValueError를 발생시킨다.)


결론: 일일이 하는 것도 중요하다. 원리를 이해하게 되니까. 대신 함수를 알면 매우 간편하고 시간도 아낄 수 있다. 함수들을 잘 활용하도록 하자!

 

 

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

 

10809번: 알파벳 찾기

각각의 알파벳에 대해서, a가 처음 등장하는 위치, b가 처음 등장하는 위치, ... z가 처음 등장하는 위치를 공백으로 구분해서 출력한다. 만약, 어떤 알파벳이 단어에 포함되어 있지 않다면 -1을 출

www.acmicpc.net

 


원래는 블로그에 올리려던 문제가 아니었다.

처음에 풀었을 때, 너무 쉽게 수월하게 풀었기 때문이다.

사실 그래서 어떻게 풀었는지조차 기억이 안나는 문제...

 

문제는 두 번째 풀려고 오늘 건드렸을때, 전혀 풀리지 않았다는 것이다.

브론즈II라는 등급에 사로잡혀 어려울 것이라고 생각했기 때문일까?

잘 모르겠지만, 굉장히 막혀버렸고, 매우 부끄럽지만 거의 2시간 이상동안 해결하지 못했던 것 같다 (처음 풀었을 때는 5~10분 걸렸던 문제였는데도 말이다...)

 

그래서 아무래도 정리할 필요성을 느끼고 다시 올리기로 하였다.

 

참고로 2시간 이상동안 못 풀었던 이유는 2번째 for문에서부터 잘못 풀었기 때문이다.

len(Num)으로 받아서 O, X를 처리하기만 하면 되는데 이 부분에서 너무 꼬아서 생각했던 것 같다.

cnt를 1씩 늘리고, cnt를 다시 score에 넣으면 되는 간단한 구조를, 

전체 배열에 ox를 일일이 집어넣고, 

해당 for문에 다시 for문을 넣어서 뒤에 있는 ox를 기준으로 둬서, 그 앞의 배열의 값을 구하려고 하니...

이런 형태로 하면 파이썬의 경우 for문을 reversed()를 통해서 sliced를 통해서 뭔가를 하려고 했다....

아무튼 엉망이고, 

결론은 그냥 간단히 생각해서 풀면 되는 것이다... 

 

최근 들어 이상하게 간단하게 해결하면 되는 문제들이 안 풀리는 느낌이 있는데...

일단 오늘을 기점으로 다시 차분하고 간단하게 생각을 해봐야 할 것 같다.


참고로 위의 코드는 다음과 같이 짜면 된다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
= int(input())
for i in range(n):
    Num = input()
    score = 0
    cnt = 0
    for j in range(len(Num)):
        if Num[j] == 'O':
            cnt += 1
            score += cnt
        elif Num[j] == 'X':
            score += 0
            cnt = 0
    print(score)
 
cs

 

 

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

 

8958번: OX퀴즈

"OOXXOXXOOO"와 같은 OX퀴즈의 결과가 있다. O는 문제를 맞은 것이고, X는 문제를 틀린 것이다. 문제를 맞은 경우 그 문제의 점수는 그 문제까지 연속된 O의 개수가 된다. 예를 들어, 10번 문제의 점수

www.acmicpc.net


상당히 고전했던 문제다.

다 풀었다고 생각했는데 틀리고, 수정했는데 또 틀리는 그런 형태의 문제

구현 자체에 대한 문제도 있었지만, 

아무래도 문제 자체가 수학, 그중에서도 기하학에 대한 개념이 있어야 했기에 더 어려움을 가졌던 것 같다.

 

우선 이 문제를 알기 위해서는 반드시 알아야 할 것이 "원의 내접과 외접, 그리고 위치 관계"에 대한 부분이다.

자세한 부분은 일단 다음 사이트를 참조하는 것이 최고다.

 

공부 참조 출처: https://mathbang.net/101

 

두 원의 위치관계, 내접, 외접

위치관계 또 나오네요. 이번에는 두 원의 위치관계에요. 위치관계 마지막이니까 정신 바짝 차리고 따라오세요. 원과 직선의 위치관계, 원의 할선과 접선, 접점에서 했던 것처럼 두 원이 어떤 관

mathbang.net

 


위의 내용을 알기 전에는 다음과 같이 코딩을 하였다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 시도1
test_case = int(input())  # 테스트 케이스 갯수
for i in range(test_case):
    x1, y1, r1, x2, y2, r2 = list(map(int, input().split()))  # 조규현 좌표(x1, y1)과 백승환 좌표(x2, y2)와 류재명과의 거리 r1, r2
    distance = ((x2 - x1) ** 2 + (y2 - y1) ** 2** 0.5
    if distance == 0:
        if r1 != r2:  # 류가 있을 수 있는 위치가 존재하지 않는다.
            print(0)
        else:  # 류가 있을 수 있는 위치는 r1(=r2)를 반지름으로 가진 원의 위치 중 어디든 가능하다.
            print(-1)
    else:
        if (r1+r2) == distance:  # r1과r2가 만나는 지점 1군데에서 류가 있을 수 있다.
            print(1)
        elif (r1+r2) > distance:  # r1+r2가 더 크다면 distance 직선기준으로 아래 위로 총 2군데 발생할 수 있다.
            print(2)
        else:
            pass
cs

하지만 계속 백준에서 틀렸다고 나왔고, 그래서 결국 기억을 짜내서 원의 내접과 외접이 생각나서 인터넷 검색을 통해서 조건을 알게 되었다.

 

조건을 정리하자면 다음과 같다.

계산한 거리는 반지름으로 r1, r2(r1 > r2)를 가지고, 두 중심간의 거리를 d라고 가정할 때
두 점에서 만나는 경우
d != 0 and r1 - r2 < d < r1 + r2
한 점에서 만나는 경우
d != 0 and { r1+r2 = d (외접) r1-r2 = d(내접)}
한 점에서도 만나지 않을 경우
d = 0 and r1 - r2 != 0
d != 0 and r1 + r2 > d
무수히 많은 점에서 만날 경우
d = 0 and r1 - r2 = 0

 

이런 조건들을 통해서 다시 만든 코드는 다음과 같다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 시도2
test_case = int(input())  # 테스트 케이스 갯수
for i in range(test_case):
    x1, y1, r1, x2, y2, r2 = list(map(int, input().split()))  # 조규현 좌표(x1, y1)과 백승환 좌표(x2, y2)와 류재명과의 거리 r1, r2
    distance = ((x2 - x1) ** 2 + (y2 - y1) ** 2** 0.5
    if distance == 0:
        if r1 != r2:  # 류가 있을 수 있는 위치가 존재하지 않는다.
            print(0)
        else:  # 류가 있을 수 있는 위치는 r1(=r2)를 반지름으로 가진 원의 위치 중 어디든 가능하다.
            print(-1)
    else:
        if (r1+r2) == distance or abs(r1-r2) == distance:  # r1과r2가 만나는 지점 1군데에서 류가 있을 수 있다.
            print(1)
        elif (r1+r2) > distance and abs(r1-r2) < distance:  # r1+r2가 더 크다면 distance 직선기준으로 아래 위로 총 2군데 발생할 수 있다.
            print(2)
        else:
            pass
cs

문제는 위의 코드도 틀렸다는 점이다.

틀린 이유는 else문 내의 else문 때문이다.

else문의 경우 pass가 아닌 0을 출력해야 하기 때문이다. 이유는, if-elif를 통해서 찾을 수 있는 경우들을 제외하면 점을 가질 수 없기 때문이고, 점이 없을 때는 0을 출력해야 하기 때문이다.

(이 틀린 부분을 찾기 위해서 상당히 오랜 시간이 걸렸다....)

 

결론적으로 제대로 된 코드는 다음과 같다!!!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
test_case = int(input())  # 테스트 케이스 갯수
 
for i in range(test_case):
    x1, y1, r1, x2, y2, r2 = list(map(int, input().split()))  # 조규현 좌표(x1, y1)과 백승환 좌표(x2, y2)와 류재명과의 거리 r1, r2
    distance = ((x2 - x1) ** 2 + (y2 - y1) ** 2** 0.5
    if distance == 0:
        if r1 != r2:  # 류가 있을 수 있는 위치가 존재하지 않는다.
            print(0)
        else:  # 류가 있을 수 있는 위치는 r1(=r2)를 반지름으로 가진 원의 위치 중 어디든 가능하다.
            print(-1)
    else:
        if (r1+r2) == distance or abs(r1-r2) == distance:  # r1과r2가 만나는 지점 1군데에서 류가 있을 수 있다.
            print(1)
        elif (r1+r2) > distance and abs(r1-r2) < distance:  # r1+r2가 더 크다면 distance 직선기준으로 아래 위로 총 2군데 발생할 수 있다.
            print(2)
        else:
            print(0)
 
cs

상당히 오래 걸린 문제이고, 결국에는 원의 내접과 외접에 대해서 알아야 했던 문제이다.

보아하니 원의 내접과 외접은 중학교 수준의 문제라는 것 같다... 

 

 

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

 

1002번: 터렛

각 테스트 케이스마다 류재명이 있을 수 있는 위치의 수를 출력한다. 만약 류재명이 있을 수 있는 위치의 개수가 무한대일 경우에는 -1을 출력한다.

www.acmicpc.net


간단한 if-else로 해결되는 문제로 생각했고 그렇게 풀었다.

그런데 알고보니 파이썬의 count를 통해서 더 쉽게 풀 수 있더라.

 

일단 if-else문으로 만든 코드는 다음과 같다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
for i in range(3):
    one_zero = list(map(int, input().split()))
    cnt_one = 0
    for j in one_zero:
        if j == 0:
            cnt_one += 1
    if cnt_one == 1:  # 도
        print('A')
    elif cnt_one == 2:  # 개
        print('B')
    elif cnt_one == 3:  # 걸
        print('C')
    elif cnt_one == 4:  # 윷
        print('D')
    else:  # 모
        print('E')
cs

다만 위의 코드와 다르게 count를 사용해서 코드를 만든다면 다음과 같다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
lists = [0]*4
for i in range(3):
    lists = list(map(int, input().split()))
    if lists.count(0== 1:
        print('A')
    elif lists.count(0== 2:
        print('B')
    elif lists.count(0== 3:
        print('C')
    elif lists.count(0== 4:
        print('D')
    elif lists.count(0== 0:
        print('E')
 
cs

 

★count()함수를 통해서 쉽게 괄호 안의 문자나 숫자가 list안에 몇 개가 포함되어있는지 셀 수 있다는 것을 알아두자!!

 

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

 

2490번: 윷놀이

우리나라 고유의 윷놀이는 네 개의 윷짝을 던져서 배(0)와 등(1)이 나오는 숫자를 세어 도, 개, 걸, 윷, 모를 결정한다. 네 개 윷짝을 던져서 나온 각 윷짝의 배 혹은 등 정보가 주어질 때 도(배 한

www.acmicpc.net

 


간단한 피보나치 수열 문제이다.

파이썬으로 만들어보기는 처음이라서 살짝 해매긴 했지만 그래도 금방 성공

1
2
3
4
5
6
7
8
9
10
11
12
= int(input())
res = [0]*(n+1)
 
for i in range(n+1):
    if i == 0:
        res[i] = 0
    elif i == 1:
        res[i] = 1
    else:
        res[i] = res[i-1+ res[i-2]
print(res[n])
# print(res)
cs

 

 

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

 

2747번: 피보나치 수

피보나치 수는 0과 1로 시작한다. 0번째 피보나치 수는 0이고, 1번째 피보나치 수는 1이다. 그 다음 2번째 부터는 바로 앞 두 피보나치 수의 합이 된다. 이를 식으로 써보면 Fn = Fn-1 + Fn-2 (n ≥ 2)가

www.acmicpc.net

 

어렵게 생각해서 막혔던 문제


문제를 너무 어렵게 꼬아서 해답을 찾으려고 하면 오히려 늪에 빠져서 답이 보이지 않고 재미가 없어지면서 자심감도 뚝뚝 떨어지는 문제들이 있다.

지금 실력에서 이런 문제들을 겪었다고 하기에는 부끄러운 문제이지만 1032번 문제가 나에게는 그랬다.

제대로 파이썬을 접하고 공부하기 시작한지 이제 2~3주차가 되어가는 것 같은데 아직도 이런 문제에서 해맨다는 사실이 좀 서글프긴 하다.

 

아무튼, 현재 문제를 너무 꼬아서 생각해버리는 바람에 완전히 막혔던 문제이다.

내가 하려던 방법의 코드를 먼저 적고 시작하겠다.

 

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
= int(input())  # 파일 이름의 갯수
string = [0]*N  # string을 input으로 받기 때문에(그리고 input은 문자열을 한 줄로 받는다.) *N이 필요하다.
 
# 단어를 입력한다.
for i in range(N):
    string[i] = input()
    # print(string)
 
# 단어들에서 같은 부분 찾기
same = list()
cnt_one = 0
for i in string[0]:  # 기준이 되는 string을 첫 번재 입력 string으로 하도록 한다.
    # print(i)
    for j in string[cnt_one+1]:
        if i == j:
            same.append(i)
        else:
            break
    same.append('?')
 
cnt_two = 1
= 0
for i in same:
    for j in string[cnt_two+1]:
        if i == j:
            same[n].append(i)
            n += 1
 
cs

참고로 당연히 오류 가득하고 실행도 안되면서 복잡하기만 한 미완성의 코드이다.

이걸 올리는 이유는 추후에 내가 이 문제를 다시 보게 되었을 때, 내가 얼마나 복잡하게 문제들을 접근하려고 했는지 정리하기 위함이다.

 

위의 코드에서 내가 노렸던 것은 배열을 사용하는 것이다(결국 주력언어인 C에서 벗어나지 못한 나의 보습이 보인다. 파이썬에서는 배열이라기보다는 "list"이기 때문...)

배열을 통해서 첫 번째 입력했던 단어와 다음 단어를 비교해서 같으면 same이라는 배열에 넣고, 그렇지 않으면 ?로 채우고자 하였다.

그 다음에 하고 자 한 것은 line 23에서부터이다. same에서 만들어진 것을 이제 그 다음 단어와 비교를 하는 것이다. 그리고 그것을 다시 same에 똑같이 대입하는 형태...

아무튼 망했다.

 


 

깔끔하게 정확하게(?) 문제를 해결한 코드는 다음과 같다:

1
2
3
4
5
6
7
8
9
10
= int(input())
pivot_word = list(input())
pivot_word = len(pivot_word)
for i in range(N - 1):
    other_words = list(input())
    for j in range(pivot_word):
        if pivot_word[j] != other_words[j]:
            pivot_word[j] = '?'
print(''.join(pivot_word))
 
cs

 

사실 이 코드 또한 스스로 해내었다기보다는 다른 분들이 해낸 것을 토대로 공부를 통해 도출한 코드나 다름없다.

그런데 보면 아이디어는 굉장히 간단하다.

나의 경우, 새로운 배열을 생성해서 거기에 넣으려고 한데에 반해, 위의 코드는 pivot_word인 첫번째로 입력한 리스트변수에 바로 처리를 하는 것이다.

 

암튼 반성해야 할 점은 명확하다.

문제가 해결이 되지 않을 때 조금 더 다른 방법을 생각해보려는 노력이 필요하다.

결국 논리력을 기를 필요가 있다... 

 

 

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

 

1032번: 명령 프롬프트

첫째 줄에 파일 이름의 개수 N이 주어진다. 둘째 줄부터 N개의 줄에는 파일 이름이 주어진다. N은 50보다 작거나 같은 자연수이고 파일 이름의 길이는 모두 같고 길이는 최대 50이다. 파일이름은

www.acmicpc.net


제목에 써있는 그대로 조금 햇갈렸던 문제이다.

문제를 푸는데 있어서 이 문제야말로 구현이 어려운 것이 아니라 규칙을 찾는 컴퓨팅적 사고 및 논리력이 필요한 문제가 아닌가 싶다.

즉, 문제를 제대로 이해하고 반례까지 없도록 잘 만드는 것이 관건이다.

나는 일부만 제대로 하고, 반례가 생기도록 처음에 만들어서 고생했다.

 

나의 첫 시도(잘못된 코드)는 다음과 같다:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 틀렸다고 나오는 코드
# 1 1 1  ==>  답 101  ==>  출력 102
= int(input())
for i in range(a):  # 몇 개의 출력물을 원하는가
    H, W, N = map(int, input().split())  #입력
    hundred = int(N % H)  #몇 층인지 찾기(백의 자리수 시작)
    decimal = int(N // H) + 1  #몇 호인지 찾기(일의 자리수 시작)
    if (hundred == 0):  # 예를 들어, N층인데 나머지가 0이면, N을 출력한다.
        hundred = H
        if(len(str(decimal)) == 1):  # 일의 자리수 시작해서 십의자리까지 넘어가지 않으면(==> 1~9이면)
            print(f"{hundred}0{decimal}")  # 0을 십의 자리수에 출력한다.
        else:
            print(f"{hundred}{decimal}")  # 십의자리수까지 출력한다.
    else:
        if(len(str(decimal)) == 1):
            print(f"{hundred}0{decimal}")
        else:
            print(f"{hundred}{decimal}")
 
cs

이 코드의 반례는 1 1 1이다. 101이라는 숫자가 나와야 하는데 decimal = int(N//H)+1을 해버렸기 때문에 틀려버렸다.

추가적으로, if~else문을 통해서 print문을 복잡하게 짠 것도 가독성이 떨어지며 속도에도 별로 좋지 않다.


고민을 하고 인터넷을 검색한 결과 다음과 같은 코드가 깔끔하다는 것을 깨닫게 되었다.

1
2
3
4
5
6
7
8
9
10
11
12
= int(input())
for i in range(a):
    H, W, N = map(int, input().split())
    hundred = N % H
    if (hundred == 0):
        hundred = H * 100
        decimal = N // H
    else:
        hundred = (N % H) * 100
        decimal = N // H + 1
    print(hundred + decimal)
 
cs

딱 봐도 깔끔하다. 특히, 내가 위에서 틀린 부분이 확연히 보인다.

decimal이라고 되어있는 부분은 hundred변수가 0일 때와 아닐 때에 따라서 다르게 처리가 되도록 해야한다.

 

이 문제의 경우, 구현의 문제나 파이썬이라는 공부에 있어서의 문제라기보다 논리적 해결의 차원에 문제로 분석할 수 있다 (물론 매우 간단한 문제이지만...).

이런 형태의 문제가 있음을 인지하고, 끊임없이 컴퓨팅적 사고를 기를 필요성을 다시 한 번 느끼게 된다.

 

 

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

 

10250번: ACM 호텔

프로그램은 표준 입력에서 입력 데이터를 받는다. 프로그램의 입력은 T 개의 테스트 데이터로 이루어져 있는데 T 는 입력의 맨 첫 줄에 주어진다. 각 테스트 데이터는 한 행으로서 H, W, N, 세 정수

www.acmicpc.net


직각삼각형은 변의 길이가 3개가 주어졌을 때, 가장 큰 수의 제곱이 다른 두 수의 제곱과 같은 값을 가진다.

이 특징을 사용해서 코딩을 하면 된다.

1
2
3
4
5
6
7
8
9
10
11
12
13
while True:
    tri = list(map(int, input().split()))
    sorted_tri = sorted(tri)
    if sorted_tri[0== 0 or sorted_tri[1== 0 or sorted_tri[2== 0:  # 마지막 줄에 주어지는 입력 케이스이다: 0 0 0
        break
    else:
        pass
 
    if(sorted_tri[0]**2 + sorted_tri[1]**2== sorted_tri[2]**2:
        print("right")
    else:
        print("wrong")
 
cs

 

 

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

 

4153번: 직각삼각형

입력은 여러개의 테스트케이스로 주어지며 마지막줄에는 0 0 0이 입력된다. 각 테스트케이스는 모두 30,000보다 작은 양의 정수로 주어지며, 각 입력은 변의 길이를 의미한다.

www.acmicpc.net

 

+ Recent posts