728x90
반응형

문제 출처 https://programmers.co.kr/learn/courses/30/lessons/42578

 

문제 설명

스파이들은 매일 다른 옷을 조합하여 입어 자신을 위장합니다.

스파이가 가진 의상들이 담긴 2차원 배열 clothes가 주어질 때 서로 다른 옷의 조합의 수를 return 하도록 solution 함수를 작성해주세요.

제한사항

clothes의 각 행은 [의상의 이름, 의상의 종류]로 이루어져 있습니다.

스파이가 가진 의상의 수는 1개 이상 30개 이하입니다.

같은 이름을 가진 의상은 존재하지 않습니다.

clothes의 모든 원소는 문자열로 이루어져 있습니다.

모든 문자열의 길이는 1 이상 20 이하인 자연수이고 알파벳 소문자 또는 '_' 로만 이루어져 있습니다.

스파이는 하루에 최소 한 개의 의상은 입습니다.

 

휴 40분 걸렸다

수학문제에 더 가까운 것 같은 문제.

의상카테고리가 하나일 때는 그 카테고리에 있는 개수를 출력하기만 하면 되지만

카테고리의 개수가 3개 이상으로 점점 늘어날수록 한 카테고리의 의상은 아예 선택하지 않는 경우까지 고려해야하다보니 구현을 어떻게 해야할지 통 감이 안와서 시간이 많이 걸렸다.

딕셔너리랑 각 카테고리별 요소 개수를 저장하는 리스트구현까지는 성공했는데

그 이후에 답을 얻어내는 과정을 모르겠어서 결국 답을 치팅했다.

(요소개수 + 1) 의 모든 곱이라니..

치팅하고 나서 공식으로 풀어보니까 위와 같이 기가막히게 똑같이 나왔다.

그래도 딕셔너리 밸류에 리스트를 넣는 등 테크니컬적인 부분에서는 공부가 됐다.

 

def solution(clothes):
    from collections import defaultdict
    d = defaultdict(list)
    def multi(arr):
        ans = 1
        for i in arr:
            ans *= (i+1)
        return ans
    for i in range(len(clothes)):
        d[clothes[i][1]] += [clothes[i][0]]
    lengths = [len(v) for v in d.values()]
    if len(lengths)==1:
        return lengths[0]
    else: return (multi(lengths) -1)
728x90
반응형
728x90
반응형
    • 올바른 괄호

darklight

sublimevimemacs

Python3 

문제 설명

괄호가 바르게 짝지어졌다는 것은 '(' 문자로 열렸으면 반드시 짝지어서 ')' 문자로 닫혀야 한다는 뜻입니다. 예를 들어

  • ()() 또는 (())() 는 올바른 괄호입니다.
  • )()( 또는 (()( 는 올바르지 않은 괄호입니다.

'(' 또는 ')' 로만 이루어진 문자열 s가 주어졌을 때, 문자열 s가 올바른 괄호이면 true를 return 하고, 올바르지 않은 괄호이면 false를 return 하는 solution 함수를 완성해 주세요.

제한사항

  • 문자열 s의 길이 : 100,000 이하의 자연수
  • 문자열 s는 '(' 또는 ')' 로만 이루어져 있습니다.

입출력 예

sanswer

()() true
(())() true
)()( false
(()( false

입출력 예 설명

입출력 예 #1,2,3,4
문제의 예시와 같습니다

 

 

1차 : 실패한 풀이

def solution(s):
    answer = True
    while True:
        temp = s.replace('()','')
        if s == temp:
            break
        s = temp
    if not s:
        return True
    else: return False

결과는 테스트케이스에서 기대한 값과 같게 나왔지만 시간초과의 이유로 효율성 점수가 낮게 나왔다.

백준에서도 괄호의 완전성을 따지는 비슷한 문제가 있었는데,

그 때도 완전한 괄호를 replace로 바꾸면서 반복했을 때 시간초과가 났던 기억이 있어 다른 방법을 생각했다.

 

2차: 성공

def solution(s):
    t = []
    for i in s:
        if i=="(":
            t.append(i)
        else:
            if t:
                t.pop()
            else: return False
    if t: return False
    else: return True

스택으로 풀면 해결할 수 있다.

728x90
반응형
728x90
반응형

문제 설명

오픈채팅방

카카오톡 오픈채팅방에서는 친구가 아닌 사람들과 대화를 할 수 있는데, 본래 닉네임이 아닌 가상의 닉네임을 사용하여 채팅방에 들어갈 수 있다.

신입사원인 김크루는 카카오톡 오픈 채팅방을 개설한 사람을 위해, 다양한 사람들이 들어오고, 나가는 것을 지켜볼 수 있는 관리자창을 만들기로 했다. 채팅방에 누군가 들어오면 다음 메시지가 출력된다.

[닉네임]님이 들어왔습니다.

채팅방에서 누군가 나가면 다음 메시지가 출력된다.

[닉네임]님이 나갔습니다.

채팅방에서 닉네임을 변경하는 방법은 다음과 같이 두 가지이다.

  • 채팅방을 나간 후, 새로운 닉네임으로 다시 들어간다.
  • 채팅방에서 닉네임을 변경한다.

닉네임을 변경할 때는 기존에 채팅방에 출력되어 있던 메시지의 닉네임도 전부 변경된다.

예를 들어, 채팅방에 Muzi와 Prodo라는 닉네임을 사용하는 사람이 순서대로 들어오면 채팅방에는 다음과 같이 메시지가 출력된다.

Muzi님이 들어왔습니다.
Prodo님이 들어왔습니다.

채팅방에 있던 사람이 나가면 채팅방에는 다음과 같이 메시지가 남는다.

Muzi님이 들어왔습니다.
Prodo님이 들어왔습니다.
Muzi님이 나갔습니다.

Muzi가 나간후 다시 들어올 때, Prodo 라는 닉네임으로 들어올 경우 기존에 채팅방에 남아있던 Muzi도 Prodo로 다음과 같이 변경된다.

Prodo님이 들어왔습니다.
Prodo님이 들어왔습니다.
Prodo님이 나갔습니다.
Prodo님이 들어왔습니다.

채팅방은 중복 닉네임을 허용하기 때문에, 현재 채팅방에는 Prodo라는 닉네임을 사용하는 사람이 두 명이 있다. 이제, 채팅방에 두 번째로 들어왔던 Prodo가 Ryan으로 닉네임을 변경하면 채팅방 메시지는 다음과 같이 변경된다.

Prodo님이 들어왔습니다.
Ryan님이 들어왔습니다.
Prodo님이 나갔습니다.
Prodo님이 들어왔습니다.

채팅방에 들어오고 나가거나, 닉네임을 변경한 기록이 담긴 문자열 배열 record가 매개변수로 주어질 때, 모든 기록이 처리된 후, 최종적으로 방을 개설한 사람이 보게 되는 메시지를 문자열 배열 형태로 return 하도록 solution 함수를 완성하라.

제한사항

  • record는 다음과 같은 문자열이 담긴 배열이며, 길이는 1 이상 100,000 이하이다.
  • 다음은 record에 담긴 문자열에 대한 설명이다.
    • 모든 유저는 [유저 아이디]로 구분한다.
    • [유저 아이디] 사용자가 [닉네임]으로 채팅방에 입장 - Enter [유저 아이디] [닉네임] (ex. Enter uid1234 Muzi)
    • [유저 아이디] 사용자가 채팅방에서 퇴장 - Leave [유저 아이디] (ex. Leave uid1234)
    • [유저 아이디] 사용자가 닉네임을 [닉네임]으로 변경 - Change [유저 아이디] [닉네임] (ex. Change uid1234 Muzi)
    • 첫 단어는 Enter, Leave, Change 중 하나이다.
    • 각 단어는 공백으로 구분되어 있으며, 알파벳 대문자, 소문자, 숫자로만 이루어져있다.
    • 유저 아이디와 닉네임은 알파벳 대문자, 소문자를 구별한다.
    • 유저 아이디와 닉네임의 길이는 1 이상 10 이하이다.
    • 채팅방에서 나간 유저가 닉네임을 변경하는 등 잘못 된 입력은 주어지지 않는다.

입출력 예

recordresult

["Enter uid1234 Muzi", "Enter uid4567 Prodo","Leave uid1234","Enter uid1234 Prodo","Change uid4567 Ryan"] ["Prodo님이 들어왔습니다.", "Ryan님이 들어왔습니다.", "Prodo님이 나갔습니다.", "Prodo님이 들어왔습니다."]

입출력 예 설명

입출력 예 #1
문제의 설명과 같다.

 

 

def solution(record):
    answer = []
    d = {}
    for i in range(len(record)):
        record[i] = record[i].split()
    for i in range(len(record)):
        if record[i][0] == 'Enter':
            answer.append([record[i][1], '님이 들어왔습니다.'])
            d[record[i][1]] = record[i][2]
        elif record[i][0] == 'Leave':
            answer.append([record[i][1], '님이 나갔습니다.'])
        elif record[i][0] == 'Change':
            d[record[i][1]] = record[i][2]
    for i in range(len(answer)):
        answer[i][0] = d[answer[i][0]]
        answer[i] = ''.join(answer[i])
    return answer

 

유저ID와 닉네임을 연동할 필요성이 있음을 느껴 딕셔너리를 이용했다.

answer 리스트 안에 1차적으로 user id를 저장해두고

Enter 나 Change를 통해 닉네임이 변경된 것이 있다면 변경사항이 적용되도록 했다.

split으로 분리해놓은 문자열 배열을 ''.join을 통해 다시 합쳤다.

728x90
반응형

+ Recent posts