[BOJ]백준#4374 Silver 1 지프의 법칙👆✔ (Python, 파이썬)

임준성·2022년 8월 17일
0

백준 Algorithm

목록 보기
51/59
post-thumbnail

백준 4374번
https://www.acmicpc.net/problem/4374

문제



후기

⏰ 풀이시간 4시간 ++⏰

맞힌 사람이 많지 않은 문제를 풀기 위해 풀은 사람이 적은 순으로 정렬해서

찾은 문제의 9번째다.

맞힌 사람이 많지 않은 문제를 푸는 것의 장점을 찾았다.

그것은 바로 아무리 답답해도 구글링으로 절대 남의 코드를 볼 수 없이 내가 풀어야 한다는 것이다.

문제의 요구사항을 알아보자면, 여러 테스트 케이스로 주어지는데 각 테스트 케이스 마다 N이 주어진다.

각 테스트 케이스의 문자열들은 문자가 아닌 것으로 이루어져 있는데

이것이 뜻하는 바는

공백으로만 문자를 구분하는 것이 아니라, 알파벳 대문자, 소문자를 제외한 모든 문자로 구분된다.

라는 것이다. 즉 1 2 : > < ! = ? ; 7 0 @#*( 를 포함하여 이러한 문자들이 나오면 단어를 구분짓는다.

단순히 .split() 을 하는 방법으로는 안된다는 얘기다.

이 문제를 나는 미리 a부터 z, A부터 Z까지 모두 들어간 list를 선언해두고, 그 list에 해당 문자열이 있지

않으면 단어를 구분하는 식으로 했다.

우선 이 문제의 접근 방법의 순서는 아래와 같은 순서로 했다.

  1. 문자열을 한 글자씩 돌면서, low_li에 있으면 저장한다.
  2. 만약 low_li에 없으면, 단어를 구분지어야 한다는 얘기이므로, 지금까지 저장된 문자열을 합쳐서
    new_word에 저장한다.
  3. 해당 단어를 딕셔너리에 저장한다.
  4. 모든 문자를 다 딕셔너리에 저장한뒤, 딕셔너리를 돌면서 N과 일치하는 value값을 가진 문자를 출력
  5. 출력이 한번도 이뤄지지 않았으면 There is no such word. 라고 출력한다.

출력이 잘못되었다고 계속 틀렸던 이유가
테스트 케이스 사이에는 공백이 한줄 존재해야 한다고 문제에서 언급되어있는데,
실제로 출력값도 마지막 출력 뒤에는 공백이 존재하지 않았다.

예를 들면
(1)

1을 출력
여백
2를 출력
여백

(2)

1을 출력
여백
2를 출력

중에서 문제의 정답은 2번으로 출력하라는 것이라고 예제 출력에서 봐서 그렇게 구현했다.

이 한줄의 여백때문에 정말 별별 과정을 다 겪으며 수정해봤지만...

문제에서 요구했던 것은 사실 (1) 으로 출력하는 것이었다..

내가 문제를 잘못 이해한 것인지는 모르겠으나... 어쨌든 나중에 무엇인가 구현 하면서

여백 한줄 조차도 오류로 check 될 수 있기 때문에, 값진 경험이었다고 생각한다.

문자열과 여백, 해시, 맵에 대해서 어려움을 겪고 있다면 이 문제를 풀어보는 것을 강력추천한다.

low_li = [ chr(i) for i in range(97,123)] #소문자가 들어간 리스트
up_li = [] #대문자를 담을 리스트
for i in low_li:
    up_li.append(i.upper())
for i in up_li: #low li에 대문자도 추가해서 대,소문자가 모두 들어간 list로 만든다.
    low_li.append(i)

while True:
    try:
        N = int(input())
        li= dict()
        new_word= [] #단어를 구분지어서 넣을 리스트 
        while True:
            word = list(map(str,input().split()))
            if len(word)==1 and word[0] == "EndOfText": #EndOfText가 입력되면
                new_word.sort()
                check = 0
                li = sorted(li.items(), key= lambda x:(x[0])) #dictionary를 문자열 오름차순 정렬
                li = dict(li)
                for key,values in li.items():
                    if values == N: #N번 나온 단어를 찾으면
                        print(key) #출력하고
                        check += 1 #There is no such word가 출력되지 않게한다.
                if check == 0: #출력된 단어가 없으면 실행됨
                    print("There is no such word.")
                break

            for i in word: # 띄어쓰기로 분리된 단어를 돌면서
                alp = ""
                for j in i: # 단어의 글자가 low_li에 들어가있으면
                    if j in low_li:
                        alp += j.lower() #소문자로 바꿔서 새로운 단어를 만든다.
                    elif j not in low_li: 
                        if len(alp) != 0: 
                            new_word.append(alp) # 만약 알파벳이 아닌 다른 문자가나오면 지금까지 저장된 alp를 new_word에 추가한다.
                            if alp not in li.keys():
                                li[alp] = 1
                            else:
                                li[alp] += 1
                            alp = ""

                if len(alp) != 0: #다음 띄어쓰기가 나올때까지 특수문자, 숫자등이 나오지 않았다면 
                    new_word.append(alp) #그 단어는 그대로 append하면 된다.
                    if alp not in li.keys():
                        li[alp] = 1
                    else:
                        li[alp] += 1
        print()
    except:
        break        
profile
아무띵크 있이

0개의 댓글