1.시간복잡도
1억(10^8)번이 1초의 시간이 걸린다고 생각한다.
2. 2805 나무 자르기
[문제]
1.상근이는 나무 M미터가 필요하다.
2.상근이는 절단기에 높이 H를 지정해야한다. 높이를 지정하면 톱날이 땅부터 H미터 위로 올라간다. 그리고 한 줄의 연속된 나무(자를 수 있는 나무) 전체를 절단해버린다.
3.높이가 H보다 크면 H위의 부분이 잘릴 것이고, 낮은 나무는 잘리지 않는다.
4.절단기 설정 가능 높이 >= 0
5.적어도 M미터의 나무를 가져가기 위한, 설정 높이 H의 최댓값 구하기.
[입력]
1.첫째 줄에 나무의 수 N과 필요한 나무 길이 M이 주어진다. ex) 4 7
2.둘째 줄에 나무의 높이가 주어진다. 나무의 높이들은 항상 >=M(필요한 나무 길이) 따라서 항상 가져갈 수 있음.
ex) 20 15 10 17
[첫 번째 문제 풀이] - 틀린 코드
N, M = map(int, input().split())
trees=list(map(int, input().split()))
trees.sort(reverse=True)
if len(set(trees))==1:
if M==0:
height=0
else:
for i in range(1, len(trees)):
if len(trees)*i == M:
height=i
break
else:
step=0
height=0
for i in range(len(trees)-2):
if M==0:
break
start = trees[i]
end = trees[i+1]
step+=1
for j in range(start-end):
if M==0:
break
M=M-step #이때 step은 획득되는 길이
height+=1
print(trees[0]-height)
위 코드대로 써보면, 진행 과정도 찍혀서 이해하기 쉽다.
문제를 푼 순서 로직은 다음과 같다.
1.먼저 나무를 내림차순으로 정렬해준다.
2.나무 길이를 앞에서부터 반복문으로 start, end로 잡고, 비교 횟수를 step으로 잡아준다. 이 비교횟수는, 해당 구간에서 1cm 이동할 때마다 1*step cm 만큼씩 얻을 수 있다는 것을 의미한다.
나무 길이를 첫 번째 예시 케이스인 20, 17, 15, 10 으로 가정해보자.
| 20 | |
| 이 구간 동안은 1cm가 1cm를 의미(구간에 있는 나무 1개) | |
| 17 | |
| 이 구간 동안은 1cm가 1*2cm를 의미 (구간에 있는 나무 2개) | |
| 15 | |
| 이 구간 동안은 1cm가 1*3cm를 의미 (구간에 있는 나무 3개) | |
| 10 | |
| 이 구간 동안은 1cm가 1*4cm를 의미 (구간에 있는 나무 4개) |
[배운점]
1..sort(reverse=False)가 디폴트이다. 내림차순 정렬하려면, .sort(reverse=True) 해주면 됨.
2.하나하나 모든 케이스를 따지는 경우에는, 예외 사항을 처리하기가 굉장히 까다롭다ㅠㅠ...하 왜 틀리는건지 답답해 죽겠네.
3.나의 잘못된 코드로 수많이 오류가 났고, 시간을 낭비했다. 물론 그 안에서 배우는 것은 많았으나, 시간을 들여서 푸는 것은 일단 어느정도 알고리즘 개념과 필수 부분들을 암기한 후에 그때 시간들여서 푸는 것으로 하자. 이론책 다 보고 문제 보려면 시간 너무 오래 걸린다. 일단 개념부터 알자.
분할정복
거듭제곱을 1억번 이상하기엔 너무 계산이 오래 걸린다. 이때, 거듭제곱을 이진수를 활용하여 계산할 수 있다.
시간복잡도, 공간복잡도
C+에서는 int보다는 long long, Java에서는 int 대신 long 쓰는게 둘 다 메모리가 4Bytes -> 8Bytes 2배이기 때문에 그냥 이것 쓰는게 마음 편하다. 부동 소수형도 float말고 double 쓰는게 마음 편하다. 실제 코딩 테스트 등에서는 이 점 반드시 지켜서, 어이없게 탈락하는 일 없게 하자. 단, overflow만 주의하고, 자신없으면 long을 쓰자.
동적계획법 계산할 때
첫 항이 반드시 하나가 아니다. 두 개, 세 개 일 수도 있으니 유의할 것.
top-down으로 먼저 연습하고, 익숙해지면 bottom-up으로 연습하자.
메모이제이션 - 동적계획법 코드 짜는 법
1) 기저 조건
2) 점화식 : 점화식을 찾는 것이 어렵고, 알고리즘 공부를 하지 않아도 풀 수 있다. 식을 찾아내는 것이 어렵다.ㅁ
3) 메모이제이션으로 저장해 줌
2517 달리기
merge sort(합병 정렬)은 분할 정복 알고리즘 중 하나입니다.
분할 정복은 문제를 작은 2개의 문제로 분리하고, 각각을 해결한 다음, 결과를 모아서 원래의 문제를 해결하는 전략입니다.
자료구조
List vs Linked List
Linked List의 경우에는 반드시 암기해줘야함.
java할 때는 배열 잡을 때, 10만 100만 작은 것을 앞으로 두기.
int[][] arr1 = new int[100][10000];
int[][] arr2 = new int[10000][100];
앞에가 작은 것이 훨씬 더 효율적이다. 정답여부까지 바뀔 수 있으니 조심하기!
트리 구조 코드를 짤 때, 사향 이진 트리(연결리스트처럼 한 줄로 연결되어 있는 트리)인지 확인이 필요하다.
-이진 트리를 표현하는 두 가지 방법
1) 연결 자료 구조 : 연결 리스트로 class 를 통해 구현 가능
2) 연속 구조 : 일차원 배열 활용하여 표현 가능(교재 참고하기, 40페이지)
문제에서 N이 10~30만이다 => NlogN 선형로그형
N이 5천정도면 2차형 알고리즘
N이 30정도다 => 팩토리얼형 등이다.
N의 수에 따라서 알고리즘 유추 가능!
이진트리 굉장히 중요하고, 이진트리는 4가지 형태가 있다.(교재 참고)
정 이진트리, 포화 이진트리, 완전 이진 트리, 사항 이진 트리
'코딩테스트 준비' 카테고리의 다른 글
| 삼성SDS 알고리즘 특강 5일차 (0) | 2024.08.02 |
|---|---|
| 삼성SDS 알고리즘 특강 4일차 : 정수론 (0) | 2024.08.01 |

