1. 1546번 평균 사기치기

    프로그래머스로만 하다가 입력 구현하려니 애먹는 중…

    →

    ㅠㅠ 로직은 쉽게 짰는데 처음 쓰는 백준에 55분 걸림.

    다행히 1시간 내에 풀어서 너무 행복해!!

    return이 아니라 print 쓰면 됐는데…

    그리 input() 은 한줄씩(개행문자 기준) 입력받음 전체가 아니라.

     n = int(input())
     sum = 0
     arr = list(map(int, input().split()))
     m = max(arr)
     for i in arr:
         if i > 0:
             sum += i / m * 100
     print(sum / n)
    

    map 함수

    map(적용할 함수, 반복가능한 자료형)

    map 객체로 리턴하기 때문에 list() 로 감싸서 형변환 필요.

    map을 쓰면 2번째 인자에 오는 것을 자동으로 for문 돌려서 1번째 인자에 오는 함수에 적용 시켜 map 객체로 append 해줌.

    ex) map(더하기 1 해주는 함수, [1,2,3]) ⇒ [2,3,4] (물론 형변환으로 안 감싸주면 map 객체 일 것임)

    1번째 인자에 이름없는 함수 즉 람다 함수를 써서 굳이 def로 함수 선언한 메소드명 안 적어도 돼서 더 편함.

    split() 은 문자열 요소를 가진 리스트를 반환하므로

    int() 함수를 이용하여 int 요소를 가진 map으로 변환 뒤 또 map을 list로 변환한것

  2. 1110번 이상한 사이클 구하기

     first = int(input())
     num = first
     cycle = 0
     while(True):
         cycle += 1
         sum = int(num / 10) + (num % 10)
         num = int(str(num % 10) + str(sum % 10))
         if num == first:
             break;
     print(cycle)
    

    으하하 38분 걸렸다.

    딱히 어려운 부분은 없었고

    처음엔 10 을 기준으로 분기 처리했다가 10을 기준으로 로직을 나누는게 의미 없다는 것을 깨닫고 if else를 삭제 한뒤 while을 무한반복문으로 바꾸고 if 절을 넣어 break 시키는 방식으로 바꿨다^_^

  3. 1157번 단어 중 가장 많은 알파벳 찾기

    ( collections.Counter([lst]) 이방식으로 더쉽게 다시풀수 있을거같음

    리스트 안에 중복제거된 값들을 key로 key 몇개씩 있는지 세줌…

    대신 Counter 객체로 반환하니까 잘 써야함

    30분 걸렸음.

from string import ascii_uppercase

word = input().upper()

dictAbc = {alpha: 0 for alpha in ascii_uppercase}

for alpha in word:
    dictAbc[alpha] += 1

arr = [key for key, value in dictAbc.items() if value == max(dictAbc.values())]

if len(arr) == 1:
    print(arr[0])
else:
    print("?")

보자마자 딕셔너리 생각이 좀 났음…

dict 초기화할때나 array 만들때 컴프리헨션 사용하면 좋음.

from string import ascii_uppercase

이건 꼭 외우자…

그리고 array 프린트할때 array 요소가 1개라고

print array 하면 [’1’] 이런식으로 어레이가 반환되니까 1을 반환하고싶으면 꼭 arr[0] 프린트해주자

이거땜에 처음에 틀려서 짜증나…

  1. 4344번 평균 넘는 학생 수 비율 구하기

    입출력 어떻게 할지 고민을 엄청 했던것 같음.

    1)여러줄 입력받아서 여러줄 출력해야할때

    input이랑 print 입출력 함수를 동시에 포문 돌리는게 가능한가 했는데 가능한가봄

     c = int(input())
     cnt = 0
     for i in range(c):
         cnt = 0
         arr = list(map(int, input().split()))
         avg = sum(arr[1:]) / arr[0] # 0 고려하기 귀찮아서 numpy.mean 사용하려 했으나 백준에서 사용불가
         for num in arr[1:]:
             if num > avg:
                 cnt += 1
         print(f"{cnt/arr[0] : .3%}")
      # .3f 말고 .3% 처럼 퍼센테이지 서식자 이용하면 자동으로 퍼센트로 계산해서 보여줌ㄷㄷ 반올림은 덤. round(실수, 보여줄소수점자리수) 이거 써도됨
    

    2)array slicing 하는법

    arr[2:3] arr[2]만

    arr[:3] 처음부터 arr[2] 까지만

    arr[3:] arr[3]부터 끝까지

    3)array sum 하는법 sum(arr) 하면됨 간편ㅎㅎ

    4)print할때 포맷팅 하는 방법 3가지

    https://mimah.tistory.com/entry/Python-문자열-포맷팅-Formating

    i) %연산자 %d, %f, %s, %%

    ex) “My name is ==%s== and my age is ==%d==” ==%== ==(”이지혜”, 28)==

    ii) format 함수

    “{string}”.format(string 안에 넣을 값)

    ex)

    “My name is =={}== and my age is =={}==”==.format(”이지혜”, 28)==

    “{==:.3f==}”.foramt(실수) 하면 3자리 이하 소수점까지만 출력하는 식 대괄호 안에 “:” 사용

    ii) f-string 포맷팅 #문자열 앞에 f를 붙이면 됨

    f”{string : 서식자}”

    위 방법 전부 자동으로 소수점 자리수 지정하면 반올림 해줌. round 안써도됨.

  2. 2869번 달팽이 나무 올라가는데 소요되는 일수 계산

     import math
        
     arr = list(map(int, input().split()))
        
     day = arr[0]
     night = arr[1]
     height = arr[2]
        
     """
     day*x  >= height + night*(x-1)
     day*x >= height + night*x - night
     day * x - night * x >= height - night
     x(day - night) >= height - night
     """
        
     print(math.ceil((height - night) / (day - night)))
    

    보자마자 while로 풀면 10^8을 초과해서 안되겠다 싶어서 방정식 구함.

    math.ceil 올림 함수 floor, round 배움.

    근데 거의 30분보다 더 적게 걸렸는데 input 읽을때 map 함수 빼먹어서 typeerror로 개고생함.

    map 그 자체로 언패킹이 가능한 리턴이라 day, night, height = map(int, input(),split()) 해도 됨.

  3. 2609번 최대공약수와 최소공배수 구하기

    40분 안걸림.

     arr = list(map(int, input().split()))
        
     for i in range(min(arr), 0, -1):
         if (max(arr) % i == 0) and (min(arr) % i == 0):
             print(i)
             break
        
     for i in range(1, 10000):
         if (max(arr) * i) % min(arr) == 0:
             print(max(arr) * i)
             break
    

    range 함수 역순으로 하는거 배움.

    range(max, 0, ==-1==) O → max, max-1, … , 1

    *==0까지 안한다는게 중요 포인트==

    range(max, 0) X

    근데 왜 range(1, 1000) 은 1, 2, …, 1000 까지 하지? 999가 아니라 ㄴㄴ 999까지함.

    • 근데 이거 유클리드 호제법으로 푸는거라고함;; 난 이상하게 풀었넹
    • 유클리드 호제법이란? 최대공약수를 구하는 알고리즘(O(logN)) # 내가 위에 푼 방식은 O(N)

      두 수 a, b가 주어지면 (a>b) a%b 즉 a를 b로 나눈 나머지 r 과 b의 최대공약수가 a,b의 최대공약수와 같다.

      r이 0이 될때 나눈 바로 그값이 GCD가 된다.

      최대공약수를 구했으면 최소공배수는 엄청 쉽게 구할수 있다.

      LCM(Least Common Multiple) = a*b / GCD

  4. 10989 인풋 받으며 수 정렬하기

    1시간 내에 못풀었다.

    처음엔 10^8 시간 초과만 안나면 될 것 같아 그냥 리스트로 input 포문 돌리고 append한 뒤 sort 함수 이용하여 정렬하고 다시 포문 돌려서 print 로 출력함.

    → 위 방식은 메모리초과가 났음…

    그래서 메모리 문제면 int형 리스트가 아니라 문자열로 바꿔서 방식 그대로(sort 대신 sorted 사용) 해봄

    → 위 방식은 메모리초과가 아닌 시간 초과가 났음…

     N = int(input())
        
     str = ''
        
     for _ in range(N):
        
         str = str + input()
        
     str = sorted(str)
        
     for i in range(len(str)):
        
         print(str[i])
     # 예제는 풀리는데 메모리 초과남...
    

    인풋이 10만개 넘어가면 빠른입력 방식으로 입력 받아야함. 안그러면 시간 초과남.

    근데 이문제는 인풋이 1000만개니까;;

    저게 문제인지 뭔지 모르겠지만 readline() 으로 바꿔도 시간초과가 나서

    결국 해설을 봤다. 리스트를 선언후 인덱스를 number로 보고 값을 몇개 출력할것인지 보고 포문 돌리며 프린트 하는 것이었다 ㅠ_ㅠ… 그래도 힌트 보고 내가 짬…

     from sys import stdin
        
     N = int(stdin.readline())
        
     lst = [0 for _ in range(10001)]
        
     for _ in range(N):
        
         lst[int(stdin.readline())] += 1
        
     for (index, value) in enumerate(lst):
        
         if value != 0:
        
             for i in range(value):
        
                 print(index)
    
    • List comprehension 초기화 하는법

      lst = [0 for _ in range(10001)]