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)]