Problem Solving (67)

문제링크

https://school.programmers.co.kr/learn/courses/30/lessons/42586?language=python3 

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

풀이

def solution(progresses, speeds):
    answer = []
    t, cnt = 0, 0
    while len(progresses) > 0:
        if progresses[0] + t*speeds[0] >= 100:
            progresses.pop(0)
            speeds.pop(0)
            cnt += 1
        else:
            if cnt > 0:
                answer.append(cnt)
                cnt = 0
            t += 1
    answer.append(cnt)
    return answer

100이 넘을때까지 전체 작업 진도를 진행시키고 작업진도>=100 이 됐을 때 맨 앞의 요소를 pop 하고 count를 증가시킨다.

작업 진도가 100이 넘지 않을때에는 count의 값이 0을 넘는지 확인하고 넘는다면 하루의 배포가 진행됐다는 것이니 answer에 추가해주고 count는 0으로 초기화한다. t는 개발 진행중인 일정로 치기 때문에 100을 넘기지 못하면 하루 증가.

리스트가 모두 비워졌을 때 남은 배포도 추가하기 위해 answer에 남은 카운트 값을 삽입한다.

문제링크

https://app.codility.com/programmers/lessons/3-time_complexity/tape_equilibrium/

 

TapeEquilibrium coding task - Learn to Code - Codility

Minimize the value |(A[0] + ... + A[P-1]) - (A[P] + ... + A[N-1])|.

app.codility.com

풀이

def solution(A):   
    first = A[0]
    second = sum(A[1:])
    res = []
    res.append(abs(first - second))
    for i in range(1, len(A)-1):
        first += A[i]
        second -= A[i]
        res.append(abs(first - second))
    return min(res)

여태 작성했던 방식이 모두 len(A)-1을 안 해서 생긴 오류라는걸 알게됐을때의 허무함...

두쪽으로 나눠야하니 리스트의 끝까지 계산하는 것이 아니라 리스트의 끝의 하나 앞에서 끊어준다.

문제링크

https://app.codility.com/programmers/lessons/3-time_complexity/perm_missing_elem/

 

PermMissingElem coding task - Learn to Code - Codility

Find the missing element in a given permutation.

app.codility.com

풀이

def solution(A):
    l = len(A)
    if l == 0:
        return 1
    else:
        return sum(range(1, l+2)) - sum(A)

처음에는 정렬을 한 후 요소를 2개씩 묶은 후 차이가 1이 아니면 빠진 요소를 찾을 수 있을 것이라 생각하고 작성했는데, 더 간단한 방법이 합을 이용하는 것이었다.

빠진 요소의 길이를 추가한만큼의 합에서 주어진 array의 합을 빼면 어떤 요소가 빠졌는지 나온다.

삽질하다 풀이를 발견해서 다행이다.

문제링크

https://app.codility.com/programmers/lessons/3-time_complexity/frog_jmp/

 

FrogJmp coding task - Learn to Code - Codility

Count minimal number of jumps from position X to Y.

app.codility.com

풀이

import math

def solution(X, Y, D):
    return math.ceil((Y-X)/D)

Y보다 크거나 같게 점프한다고 했으니 올림을 해준다. 처음엔 반올림을 생각했는데 틀렸다해서 올림을 썼다.

문제링크

https://app.codility.com/programmers/lessons/2-arrays/odd_occurrences_in_array/

 

OddOccurrencesInArray coding task - Learn to Code - Codility

Find value that occurs in odd number of elements.

app.codility.com

풀이

def solution(A):
    A.sort()
    l = len(A)
    for i in range(0, l, 2):
        # 인덱스의 끝이 답일 때 ex) 2 2 3 3 4
        if i == l-1:
            return A[i]
        if A[i] != A[i+1]:
            return A[i]

문제를 잘못 이해해서 시간을 많이 날렸다. array를 정렬하고 2스텝씩 진행했을때, 맞지 않으면 2스텝씩 묶은 첫번째 요소가 답이 된다. 하지만 만약 [2, 2, 3, 3, 4] 같은 경우는 마지막 요소를 짝을 묶을 수 없으므로 마지막 요소가 정답이 된다. 그래서 if i == l-1 조건문을 넣었다.

시간 복잡도는 O(N), O(N*log(N)) 이 나왔는데 더 줄이고 싶다...🙂 다른 사람의 풀이에서 xor 연산을 사용한 것을 봤는데 저런 두뇌회전.. 커비처럼 삼키고싶음.

문제링크

https://app.codility.com/programmers/lessons/2-arrays/cyclic_rotation/

 

CyclicRotation coding task - Learn to Code - Codility

Rotate an array to the right by a given number of steps.

app.codility.com

 

풀이

def solution(A, K):
    temp = 0
    if len(A) == 0:
        return A
    for _ in range(K):
        temp = A.pop()
        A.insert(0, temp)
    return A

첫번째 시도에서 empty array에 대해 지정을 해주지 않아 통과되지 않았다. 배열의 길이가 0일때 그대로 리턴하도록 설정하니 통과됐다.

문제링크

 

풀이

T = int(input())
for test in range(1, T+1):
    n, k = map(int, input().split())
    arr = [list(map(int, input().split())) for _ in range(n)]
    # con : 1의 개수 확인, res : k가 들어갈 수 있는 자리 개수
    con = 0
    res = 0
    for i in range(n):
        # 행
        for j in range(n):
            if arr[i][j] == 1:
                con += 1
            if arr[i][j] == 0 or j == n-1:
                if con == k:
                    res += 1
                con = 0
        # 열
        for j in range(n):
            if arr[j][i] == 1:
                con += 1
            if arr[j][i] == 0 or j == n-1:
                if con == k:
                    res += 1
                con = 0
                
    print(f"#{test} {res}")

행과 열을 따로 검사한다.

한 줄씩 읽으면서 1을 만나면 카운트에 추가, 0을 만나거나 한 줄의 끝일 때 카운트와 단어의 길이가 같은지 검사한다.

같으면 결괏값을 증가시킨다. 다음 줄 검사를 위해 카운트를 0으로 초기화한다.

문제링크

 

풀이

T = int(input())
grade = ["A+", "A0", "A-", "B+", "B0", "B-", "C+", "C0", "C-", "D0"]
for test in range(1, T+1):
    # n : 학생 수, k : 알고 싶은 학생의 번호
    n, k = map(int, input().split())
    # score[] : 학생들의 total 점수를 보관할 리스트
    score = []
    for i in range(n):
        # 중간, 기말, 과제 점수
        mid, fin, work = map(int, input().split())
        total = mid*0.35 + fin*0.45 + work*0.2
        score.append(total)

    # k의 총 점수
    k_score = score[k-1]
    score.sort(reverse=True) # 학점 부여를 위해 내림차순 정렬
    
    rate = n//10
    k_index = score.index(k_score) // rate

    print(f"#{test} {grade[k_index]}")

평점 비율을 이해하는데 시간이 많이 걸렸다.

N명의 학생이 있을 때 N/10명의 학생에게 동일한 평점을 부여한다. 만약 학생수가 30명이면 3명씩 공동 학점이기 때문에 k가 2등이라면 2//3을 했을 때 0이 나오기 때문에 학점 리스트의 0번째 인덱스 학점인 A+를 부여받는다.

문제링크

 

풀이

T = int(input())
for test in range(1, T+1):
    words = input()
    words2 = words[::-1]
    if words == words2:
        print(f"#{test} 1")
    else:
        print(f"#{test} 0")

[::-1]을 사용하면 리스트의 뒤에서부터 탐색 가능. 파이썬의 장점!

문제링크

 

풀이

T = int(input())
for test in range(1, T+1):
    n, m = map(int, input().split())
    arr = [0 for _ in range(n)]
    arr = [list(map(int, input().split())) for _ in range(n)]
    res_list = []
    for i in range(n-m+1):
        for j in range(n-m+1):
            res = 0
            for x in range(m):
                for y in range(m):
                    res = res + arr[x+i][y+j]
            res_list.append(res)
    print(f"#{test} {max(res_list)}")

2차원 배열 입력받기 arr = [list(map(int, input().split())) for _ in range(n)]

지금 다시 코드를 보면 4번째 줄을 굳이 써야 하나 싶다.

파리채는 배열의 범위를 넘지 않는 n-m+1만큼 수행

1 ··· 3 4 5 6 7