2. 알고리즘이 뭔가요?
무함마드 이븐 무사 알콰리즈미(780~850)
알콰리즈미 → 알고리즘
에츠허르 다익스트라 → 다익스트라
로버트 플로이드 -> 플로이드-워셜
Knuth – Morris – Pratt → KMP
인물의 이름에서 유래
작동 방식에서 유래
홍수가 차듯 탐색 → flood fill
당장의 최선을 선택 → greedy
일을 최대한 미루기 → lazy segment tree
3. 토끼와 거북이 알고리즘
Floyd’s cycle detection의 다른 이름
유향 그래프에서 사이클과 사이클의 시작점을 판별
Tortoise And Hare
4. 토끼와 거북이 알고리즘
0. 토끼와 거북이를 포인터로 간주
두 포인터를 같은 지점으로 초기화
1. 토끼는 2칸, 거북이는 1칸씩 전진
2. 토끼와 거북이가 만났다면, 사이클이 존재
1. 토끼는 그대로, 거북이를 시작점으로 옮김
2. 토끼와 거북이 모두 1칸씩 전진
3. 처음으로 만난곳이 사이클의 시작점
3. 포인터가 null(종점)에 다다르면 사이클이 없음
시간복잡도 : O(N) / 공간복잡도 : O(1)
Tortoise And Hare
5. 폴라드로 알고리즘
John Pollard가 고안, ρ(rho)를 닮아 붙여진 이름
• 정수를 O(N^1/4)의 시간복잡도로 소인수분해하는데 사용
• 최악의 경우 O(N), 다만 사실상 O(N^1/4)
• 인수분해 알고리즘이지만, 재귀적으로 소인수분해 가능
Pollard’s Rho
6. 다이나믹 프로그래밍
문제를 쪼개고, 답을 재활용하는 방식
알고리즘으로도 부르지만, 문제의 전형적 접근법(패러다임)에 가까움
다이나믹이라는 용어는 멋있어서 붙여진 이름
Dynamic Programming
2*1 타일링 문제
https://www.acmicpc.net/problem/11726
8. 탐색을 위해 O(N)이상의 복잡도를 갖는 프로그램은 비효율적일까?
탐색은 naive한 방법이 O(N), smart한 방법이 O(logN)이지만…
알고리즘의 평가기준이 상대적이듯, 좋은 solution의 기준도 상대적이다
9. 문제 : X번째로 큰 수(쿼리)
첫째 줄에 수의 개수 N이 주어진다. ( 1<=N<=100,000 )
둘째 줄부터 N개의 수가 주어진다.
셋째 줄에는 쿼리의 개수 M이 주어진다.( 1<=M<=100,000)
넷째 줄부터 M개의 X가 주어진다.
출력
입력
각 쿼리에 대해서 X번째로 큰 수를
공백으로 구분하여 출력한다.
예제 출력
5
2 5 1 9 7
3
2 1 5
예제 입력
7 9 1
10. 문제 : X번째로 큰 수(쿼리)
• 다양한 풀이법이 존재할 수 있는 문제
• 제안하는 방법은 정렬을 이용한 풀이방법
• 내림차순 정렬한다면, 정렬된 배열에서 단순히 x번째 수를 참조,
쿼리당 O(1)만에 정답을 구할 수 있음
• 정렬을 하는데 O(NlogN), M개의 쿼리당 O(1)이 소모되므로
O(NlogN + M)의 시간 복잡도를 갖음
11. 문제 : X번째로 큰 수(쿼리)
• 앞서 제안한 O(NlogN + M)의 풀이방법은 탐색을 위해서 정렬을 진행하지만, 효율적인 방법
• 탐색보다 정렬이 더 높은 비용이지만 // O(logN)~O(N) < O(N)~O(N^2)
문제가 변형됨에 따라 탐색문제의 smart한 풀이가 정렬이 될 수도 있음
• 문제마다 요구하는 알고리즘이 특정되어지지 않을 정도로 다양함
• 문제의 단순한 조건(ex. 수의 범위)만 바꿔도 쉬운 문제가 매우 어려운 문제로 바뀔 수 있음
• 회의실 배정 == greedy, 배낭문제 == dynamic programming같은 고정관념이 아닌
효율적인 알고리즘들을 배우며 사고를 단계적으로 확장시키는것이 중요
결론
시사점
12. Problem Solving을 위한 온라인 저지
BaekJoon Online Judge Programmers
장점 문제가 아주(약 22000문제)많음
난이도가 세분화(30단계)되어있음
‘https://solved.ac/’와 연동하여 다양한정보 제공
입출력을 제외한 solution함수를 작성하는 스타일
대부분의 코딩테스트 환경과 동일
단점 대부분의 코딩테스트 환경과 다름(입출력존재)
문제가 너무 많아서, 뭘 풀지 모르겠다…
문제수가 적음
난이도가 5단계로만 분류
https://www.acmicpc.net/ https://programmers.co.kr/learn/challenges
백준으로 시작하여, 코딩테스트를 응시할 때 프로그래머스로 옮기는 것을 추천
13. Solved.ac
• 기존 백준의 단점을 상당수 보완
• 다양한 태그와 그래프, 티어를 제공 → 동기부여+약점파악
• 알고리즘 난이도를 기준으로 학습 가이드라인(CLASS) 제공
• 깃허브와 유사한 잔디제공(!!!)
14. 어떤 프로그래밍언어를 사용해야하나요?
목적이 코딩테스트라면 파이썬이나 자바도 OK
이미 숙련된 언어가 존재한다면, 해당 언어로 먼저 시작(언어를 바꾸는건 어렵지 않다)
목적이 코딩테스트가 아닌, 취미용 PS나 대회(Competitive Programming, CP)가 목적이라면 C++이 보통
유리한 언어를 선택하는 것 보다 더 중요한건 언어에 대한 이해도
파이썬으로 대회해도, 자바로 코딩테스트 응시해도 not bad
15. PS, CP, 코딩테스트가 다른가요?
PS : 백준등의 Online Judge에서 시간제한 없이 문제를 푸는것
CP : 시간제한이 존재하는 PS
코딩테스트 : 채용목적의 CP(?), PS나 CP 에 비해 알고리즘에 대해 깊게 묻지 않음
대체로 코딩테스트는…
• 많은 요구사항으로 구현이 어려움
• 구현을 어렵게 할 목적으로 문자열의 출제율도 높음
• 언어마다 내장된 함수나 자료구조를 충분히 활용할 수 있어야 해결이 가능
• 구현, 브루트포스, 그리디, DP, BFS, DFS정도로도 합격을 바라볼 수 있음
대체로 프로그래밍 대회는…
• 이 세상에 존재하는 모든 문제를 출제
• 대회마다 문제의 성격도 다름
16. 문제풀이에 필요한 두 가지 요소
1. 구현능력 : 내가 떠올린 로직을 프로그래밍 언어로 구현하는 능력
→ 많이 풀면, 많이 늚 (질보단 양)
2. 문제해결능력 : 문제를 보고 로직을 구상하는 능력
→ 좋은 문제를 풀어야 늚 (양보단 질)
17. 문제풀이 연습 가이드라인
1. 한문제에 1시간을 넘기지 않기
넘겼다면, 다른사람의 풀이를 참고하기
2. 충분히 고민하고 코드작성을 시작하기
3. 많이 읽기 → 새로운 시각을 발견하면, 실력 수직상승
4. 내가 갖고 있는 지식을 나누기
5. 나만의 가이드라인 확립하기
6. 문제풀이를 즐기기
18. 참고한 자료&&공부자료
• geeksforgeeks : 자료 많음, 로그인하면 무료
• ko/en Wikipedia : ko Wikipedia, en Wikipedia : 수학적인 접근, 원론적인 정의
• Introduction to Algorithms : 알고리즘 교과서, 난이도 고급
• 종만북 : (대회용)교과서, 난이도 중급
• 개인 블로그, codeforce blog, 그 외 구글링해서 나온 자료