• 문제 설명
    • 어느 학교에 페인트가 칠해진 길이가 n미터인 벽이 있습니다. 
    • 벽에 동아리 · 학회 홍보나 회사 채용 공고 포스터 등을 게시하기 위해 테이프로 붙였다가 철거할 때 떼는 일이 많고 그 과정에서 페인트가 벗겨지곤 합니다.
    •  페인트가 벗겨진 벽이 보기 흉해져 학교는 벽에 페인트를 덧칠하기로 했습니다.
    • 넓은 벽 전체에 페인트를 새로 칠하는 대신, 구역을 나누어 일부만 페인트를 새로 칠 함으로써 예산을 아끼려 합니다. 
    • 이를 위해 벽을 1미터 길이의 구역 n개로 나누고, 각 구역에 왼쪽부터 순서대로 1번부터 n번까지 번호를 붙였습니다. 
    • 그리고 페인트를 다시 칠해야 할 구역들을 정했습니다.
    • 벽에 페인트를 칠하는 롤러의 길이는 m미터이고, 롤러로 벽에 페인트를 한 번 칠하는 규칙은 다음과 같습니다.
      • 롤러가 벽에서 벗어나면 안 됩니다.
      • 구역의 일부분만 포함되도록 칠하면 안 됩니다.
    • 즉, 롤러의 좌우측 끝을 구역의 경계선 혹은 벽의 좌우측 끝부분에 맞춘 후 롤러를 위아래로 움직이면서 벽을 칠합니다. 
    • 현재 페인트를 칠하는 구역들을 완전히 칠한 후 벽에서 롤러를 떼며, 이를 벽을 한 번 칠했다고 정의합니다.
    • 한 구역에 페인트를 여러 번 칠해도 되고 다시 칠해야 할 구역이 아닌 곳에 페인트를 칠해도 되지만 다시 칠하기로 정한 구역은 적어도 한 번 페인트칠을 해야 합니다. 
    • 예산을 아끼기 위해 다시 칠할 구역을 정했듯 마찬가지로 롤러로 페인트칠을 하는 횟수를 최소화하려고 합니다.
    • 정수 n, m과 다시 페인트를 칠하기로 정한 구역들의 번호가 담긴 정수 배열 section이 매개변수로 주어질 때 롤러로 페인트칠해야 하는 최소 횟수를 return 하는 solution 함수를 작성해 주세요.
  • 제한 조건
    • 1 ≤ m ≤ n ≤ 100,000
    • 1 ≤ section의 길이 ≤ n
    • 1 ≤ section의 원소 ≤ n
      • section의 원소는 페인트를 다시 칠해야 하는 구역의 번호입니다.
      • section에서 같은 원소가 두 번 이상 나타나지 않습니다.
      • section의 원소는 오름차순으로 정렬되어 있습니다.
  • 입출력 예

 

  • 실패코드
    • 테스트 1, 4,  5,  7,  8,  12,  16,  17,  18,  19,  21,  22,  26,  28,  31,  32,  33,  35,  36,  39,  43,  44,  50 실패
def solution(n, m, section):
    answer, next_v = 0, 1
    start,last = section[0], section[-1]
    
    for i in range(start,n+1,m):
        if last >= i :
            answer += 1
            while next_v < len(section): 
                if section[next_v] < i:
                    next_v += 1
                else: 
                    break
        else: break
    return answer

 

  • 수정코드
    • 생각을 해보니 칠해야 될 최대 크기는 section의 원소 갯수 만큼인걸 알 수 있다. 그래서 기존 for문을
    • for i in range(start,n+1,m) ->  for i in range(len(section)) 으로 변경
    • 안의 내용도 딱히 필요없어져서 3줄로 요약을 했다
def solution(n, m, section):
    answer = 0
    paint = 0
    
    if m == 1 : return len(section) #롤러의 길이가 1이면 결국 section의 길이만큼 칠해야 하므로 section의 길이를 리턴
        
    for i in range(len(section)): # 최대로 칠해야 되는 수는 section의 길이만큼 이다
        if section[i] < paint : continue # 이미 칠해졌는 확인 칠해졌을 해당 부분은 건너띈다
        paint = section[i] + m	#배열 가장 앞에 m 만큼 칠한다
        answer += 1	#벽을 칠했으므로 하나 카운트 
        
    return answer



'Python > Python 문제' 카테고리의 다른 글

옹알이(2)  (0) 2024.06.17
숫자 짝꿍  (0) 2024.06.16
명예의 전당 (1)  (0) 2024.06.13
문자열 내 마음대로 정렬하기  (0) 2024.06.12
시저 암호  (0) 2024.06.11
  • 문제 설명
    • "명예의 전당"이라는 TV 프로그램에서는 매일 1명의 가수가 노래를 부르고, 시청자들의 문자 투표수로 가수에게 점수를 부여합니다. 
    • 매일 출연한 가수의 점수가 지금까지 출연 가수들의 점수 중 상위 k번째 이내이면 해당 가수의 점수를 명예의 전당이라는 목록에 올려 기념합니다. 
    • 즉 프로그램 시작 이후 초기에 k일까지는 모든 출연 가수의 점수가 명예의 전당에 오르게 됩니다. 
    • k일 다음부터는 출연 가수의 점수가 기존의 명예의 전당 목록의 k번째 순위의 가수 점수보다 더 높으면, 출연 가수의 점수가 명예의 전당에 오르게 되고 기존의 k번째 순위의 점수는 명예의 전당에서 내려오게 됩니다.
    • 이 프로그램에서는 매일 "명예의 전당"의 최하위 점수를 발표합니다.
    • 예를 들어, k = 3이고, 7일 동안 진행된 가수의 점수가 [10, 100, 20, 150, 1, 100, 200]이라면, 명예의 전당에서 발표된 점수는 아래의 그림과 같이 [10, 10, 10, 20, 20, 100, 100]입니다.

    • 명예의 전당 목록의 점수의 개수 k, 1일부터 마지막 날까지 출연한 가수들의 점수인 score가 주어졌을 때, 매일 발표된 명예의 전당의 최하위 점수를 return하는 solution 함수를 완성해주세요.
  • 제한 조건
    • 3 ≤ k ≤ 100
    • 7 ≤ score의 길이 ≤ 1,000
      • 0 ≤ score[i] ≤ 2,000
  • 입출력 예

 

  • 오류 코드
def solution(k, score):
    answer = []
    if 3 > k and k > 100 : return '3 ≤ k ≤ 100'
    if 7 > len(score) and len(score) > 1000 : return '7 ≤ score의 길이 ≤ 1,000'
    ranks = []
    for i in range(len(score)):
        if score[i] < 0 and score[i] > 2000 : return '0 ≤ score[i] ≤ 2,000'
        if i < k :
            if i == 0 :
                temp = score[i]
            else:
                temp = 2001
            for j in range(i):
                if temp > score[j]:
                    temp = score[j]
            answer.append(temp)
            ranks.append(score[i])
        else:
            ranks.sort()
            for rank in ranks:
                if rank < score[i] :
                    ranks[0] = score[i]
                    break
            ranks.sort(reverse=True)
            answer.append(ranks[-1])
            
    return answer

 

테스트 1, 3, 4, 23, 26을 제외한 모든 테스트에서 실패하게 되었다. 

 

위 코드에서 를 분석하다 temp의 값이 2001이 되는 부분이 있어서 그 조건문을 제거 한 후 테스트를 돌려보니 정상적으로 통과가 되는 것을 확인 하였다.

아마도 테스트 중 필요 없는 조건문이 들어가면 안되는 것 같다. 

def solution(k, score):
    answer = []
    if 3 > k and k > 100 : return '3 ≤ k ≤ 100'
    if 7 > len(score) and len(score) > 1000 : return '7 ≤ score의 길이 ≤ 1,000'
    ranks = []
    for i in range(len(score)):
        if score[i] < 0 and score[i] > 2000 : return '0 ≤ score[i] ≤ 2,000'
        if i < k :
            temp = score[i]
            for j in range(i):
                if temp > score[j]:
                    temp = score[j]
            answer.append(temp)
            ranks.append(score[i])
        else:
            ranks.sort()
            for rank in ranks:
                if rank < score[i] :
                    ranks[0] = score[i]
                    break
            ranks.sort(reverse=True)
            answer.append(ranks[-1])
            
    return answer

'Python > Python 문제' 카테고리의 다른 글

옹알이(2)  (0) 2024.06.17
숫자 짝꿍  (0) 2024.06.16
덧칠하기  (0) 2024.06.14
문자열 내 마음대로 정렬하기  (0) 2024.06.12
시저 암호  (0) 2024.06.11
  • 문제 설명
    • 문자열로 구성된 리스트 strings와, 정수 n이 주어졌을 때, 각 문자열의 인덱스 n번째 글자를 기준으로 오름차순 정렬하려 합니다. 예를 들어 strings가 ["sun", "bed", "car"]이고 n이 1이면 각 단어의 인덱스 1의 문자 "u", "e", "a"로 strings를 정렬합니다.
  • 제한 조건
    • strings는 길이 1 이상, 50이하인 배열입니다.
    • strings의 원소는 소문자 알파벳으로 이루어져 있습니다.
    • strings의 원소는 길이 1 이상, 100이하인 문자열입니다.
    • 모든 strings의 원소의 길이는 n보다 큽니다.
    • 인덱스 1의 문자가 같은 문자열이 여럿 일 경우, 사전순으로 앞선 문자열이 앞쪽에 위치합니다.
  • 입출력 예

  • 오류 코드
def solution(strings, n):
    answer = []
    if 1 > len(strings) or len(strings) > 50: return 'strings는 길이 1 이상, 50이하인 배열입니다.'
    j = 0
    while j < len(strings):
        if len(strings[j]) < 1 or len(strings[j]) > 100 : 
            return 'strings의 원소는 길이 1 이상, 100이하인 문자열입니다.'
        if len(strings[j]) < n: return '모든 strings의 원소의 길이는 n보다 큽니다.'
        if strings[j].islower() == False : return 'strings의 원소는 소문자 알파벳으로 이루어져 있습니다.'
    
        for i in range(len(strings)-1):
            if ord(strings[i][n]) > ord(strings[i+1][n]) :
                strings[i], strings[i+1] = strings[i+1], strings[i]
            elif ord(strings[i][n]) == ord(strings[i+1][n]) :
                for k in range(len(strings[i])):
                    if ord(strings[i][k]) > ord(strings[i+1][k]) :
                        strings[i], strings[i+1] = strings[i+1], strings[i]
                        break
        j += 1
    answer = strings
    return answer

 

테스트 2~4, 6~8, 10, 12 에서 실패가 뜸

 

위의 하드코드 방식으로 정렬 하는 부분으로는 힘들거 같아서 파이썬에 제공하는 정렬 함수중 sort()를 사용하여 문제를 해결하였다.

파이썬 에서는 문자열 또는 배열을 정렬을 쉽게 하기위 하여 제공되는 함수는 sort()와 sorted()가 있다

  • sort()
    • 변수 자체가 변경된다.
    • x.sort() 
    •  
  • sorted()
    • 변수 자체가 변경되는게 아닌 변경된 부분을 리턴해준다.
    • sorted(x)
  • sort()와 sorted() 둘다 기본적으로 오름차순 정렬이며 내림차순 정렬을 위해서는 " reverse=True"  이부분이 필요하다.
def solution(strings, n):
    answer = []
    for string in strings:
        addWord = string[n] + string
        answer.append(addWord)
    answer.sort()
    
    for i in range(len(answer)):
        answer[i] = answer[i][1:]
        
    return answer

 

 

참조 사이트: https://sennieworld.tistory.com/46

 

[re-Python] 문자열, 배열 정렬 (sort, sorted)

코딩테스트에서 간간히 나오는 유형이라 모르고 지나칠 수가 없는... 근데 헤깔리는... 1차원 배열을 정렬하는 것은 매우 쉽다. [1차원 배열] Ascending Sort, 오름차순(1,2,3,...) 정렬 arr = [5,2,3,1,4] # 1번

sennieworld.tistory.com

 

'Python > Python 문제' 카테고리의 다른 글

옹알이(2)  (0) 2024.06.17
숫자 짝꿍  (0) 2024.06.16
덧칠하기  (0) 2024.06.14
명예의 전당 (1)  (0) 2024.06.13
시저 암호  (0) 2024.06.11
  • 문제 설명
    • 어떤 문장의 각 알파벳을 일정한 거리만큼 밀어서 다른 알파벳으로 바꾸는 암호화 방식을 시저 암호라고 합니다. 예를 들어 "AB"는 1만큼 밀면 "BC"가 되고, 3만큼 밀면 "DE"가 됩니다. "z"는 1만큼 밀면 "a"가 됩니다. 문자열 s와 거리 n을 입력받아 s를 n만큼 민 암호문을 만드는 함수, solution을 완성해 보세요.
  • 제한 조건
    • 공백은 아무리 밀어도 공백입니다.
    • s는 알파벳 소문자, 대문자, 공백으로만 이루어져 있습니다.
    • s의 길이는 8000이하 입니다.
    • n은 1이상, 25이하인 자연수 입니다.
  • 입출력 예

 

 

오류 코드

def solution(s, n):
    answer = ''
    if len(s) > 8000: return 's의 길이는 8000이하입니다.'
    if 1 > n and n > 25 : return 'n은 1 이상, 25이하인 자연수입니다.'
    checks = s.split(' ')
    for check in checks:
    	if check.isalpha() == False: return 's는 알파벳 소문자, 대문자, 공백으로만 이루어져 있습니다.'
        
    for word in s:
        if word == ' ': 
            word = ' '
    
        elif word.islower():
            word = chr((ord(word)-ord('a') + n) % 26 + ord('a'))
            
        elif word.isupper():
            word = chr((ord(word)-ord('A') + n) % 26 + ord('A'))
            
        answer += word
        
    return answer

 

위 코드로 제출 시 테스트 9~13번까지 오류가 발생

9~13번까지 어떤 매개변수가 오는지는 알 수 없으나 노가다 끝에 아래 코드로 변경시 오류 없이 제출 됨을 확인 했습니다.

 

def solution(s, n):
    answer = ''
    if len(s) > 8000: return 's의 길이는 8000이하입니다.'
    if 1 > n : return 'n은 1 이상, 25이하인 자연수입니다.'
    if n > 25 : return 'n은 1 이상, 25이하인 자연수입니다.'

    for word in s:
        if word == ' ': 
            word = ' '
        
        elif word.islower():
            word = chr((ord(word)-ord('a') + n) % 26 + ord('a'))
            
        elif word.isupper():
            word = chr((ord(word)-ord('A') + n) % 26 + ord('A'))
            
        else:
            return 's는 알파벳 소문자, 대문자, 공백으로만 이루어져 있습니다.'
            
        answer += word
    return answer

 

첫번째 코드와 수정한 코드의 차이는 s가 알파벳 소문자, 대문자, 공백으로만 이루어 져있는지 확인 하는 부분인데 첫번째 코드의 경우 받아온 문자열을 공백을 기준으로 나누어 리스트에 저장 후 잘려진 데이터를 불러와 isalpha() 함수를 이용하여 문자인지 확인하는 부분입니다.

수정한 코드의 경우 전체 문자열 하나 하나 가져온뒤 공백, 대소문자 확인 후 하나라도 해당이 안될 경우 오류를 리턴하게 한 부분입니다.

 

ord('a-z') - ord('a')의 경우 아스키값을 빼는 거라 숫자 0~26 까지 생성이 된 후 n 만큼 이동 시킨 후 다시 아스키 값을 더 하는 방식으로 문자를 1만큼 이동되게 할 수 있습니다.

 

테스트  9~13번이 정확히 무엇을 체크하는지 알 수 없으나 쓸모 없는 for문 사용 및 내장 함수 사용을 체크하지 않을까라는 생각을 해보며 이만 글을 마치겠습니다.

'Python > Python 문제' 카테고리의 다른 글

옹알이(2)  (0) 2024.06.17
숫자 짝꿍  (0) 2024.06.16
덧칠하기  (0) 2024.06.14
명예의 전당 (1)  (0) 2024.06.13
문자열 내 마음대로 정렬하기  (0) 2024.06.12

+ Recent posts