SlideShare une entreprise Scribd logo
1  sur  46
문제해결능력
알고리즘으로 배우는 프로그래밍적 사고
Presenter
Dongyi
Kim
아주대학교 컴퓨터공학과 재학
알고리즘 연구 동아리 ANSI 활동
가라지스토리 안드로이드 개발자 (2014)
ICTK 보안연구원 (2014 ~ 2015)
2013 ACM ICPC Asia-Daejeon Regional 13th
placed
2012 ACM ICPC Asia-Daejeon Regional 18th
placed
2013 전국 대학생 프로그래밍 경시대회 동상
정보올림피아드 지역본선 은상
정보올림피아드 지역본선 은상
정보올림피아드 지역본선 은상
정보올림피아드 지역본선 은상
정보올림피아드 지역본선 은상
Contents
알고리즘? 문제해결능력?
무엇인지, 왜 중요한지에 대해
실제로 문제를 해결해보기
실제 상황을 가정해서 적용해보기
훈련해볼 수 있는 방법
평소에 문제해결능력을 훈련할 수 있는 방법
문제해결능력
Q. 아래에서 해당하는 사항이 있나요?
- 프로그래밍을 공부했지만, 스스로 코딩을 하기는 힘들다.
- 다른 사람들에 비해 내가 짠 프로그램은 코드가 길고 성능도 좋지 않다.
- 기능이 조금만 복잡해져도 키보드에 손도 못 댈 것 같다.
- 알고리즘, 자료구조, 계산이론 … 이런 것들을 대체 왜 배우는지 모르겠다.
- 개발이 단순 반복 작업처럼 느껴지고 지루하다.
A. 해당하는 사항이 있다면? 문제해결능력을 길러야 할 때
대상 프로그래밍을 공부했고 알고리즘과 자료구조를 공부하고 있는 학생
문제해결능력
문제 무엇인가를 프로그래밍을 통해 계산, 구현, 개선해야 하는 상황
해결 속도, 효율, 정확성 등을 고려하여 문제를 해결할 가장 적합한 방법을 찾고
구현하는 것
문제해결능력
= 분석능력 + 사고력 + 지식 + 판단력 + 아이디어 + … + 알고리즘
문제해결과정
분석 요구사항, 제한사항을 확인하여 무엇을 구현할 것인가에 대한 결정
설계 다양한 사항을 고려하여 최적의 방법을 설계
구현 설계된 사항대로 정확하고 간결하게 구현
프로그래밍
언어
프로그램설계분석 구현
알고리즘이란?
알고리즘 어떠한 문제를 효율적으로 해결하기 위해 설계된 방법
자료구조 자료들을 특정한 목적에 맞게 효율적으로 저장/가공할 수 있도록
설계된 방법
즉, 알고리즘과 자료구조는 어떠한 문제를 해결하기 위해 설계된 방법
- 이미 설계되어 있는 알고리즘을 활용하여 문제를 해결할 수 있다.
- 많이 알고 있을 수록 문제해결 시 선택의 폭이 넓어진다.
- 알고리즘에 대한 충분한 이해를 하고 있다면, 이를 수정하거나 아이디어를 빌려 활용할
수 있다.
다양한 알고리즘을 공부하는 것은 문제해결능력을 기르는 효과적인
방법
알고리즘이란?
방법 속도 메모리 정확도 구현난이도
A 느리다 조금 사용 정확하다 매우 단순하다
B 빠르다 많이 사용 정확하다 보통이다
C 빠르다 조금 사용 보장못함 매우 단순하다
A2 꾀 빠르다 조금 사용 정확하다 단순하다
B2 엄청 빠르다 엄청 많이 사용 정확하다 많이 복잡하다
C2 엄청 빠르다 조금 사용 거의 근사 한다 단순하다
당신은 어떤 문제에 대해 다음과 같은 세 해결 방법을 떠올렸습니다.
‘갑 알고리즘’의 아이디어를 방법 A에 응용했더니 아래와 같이 개선 되었다.
‘을 자료구조’를 방법 B와 함께 사용했더니 아래와 같이 개선되었다.
‘병 알고리즘’을 방법 C에 활용했더니 아래와 같이 개선되었다.
이처럼 다양한 알고리즘과 아이디어에 의해 같은 문제에 대해서 다양한 해결 방법이 나올 수
있습니다.
또한, 여러 방법 중 현재 가장 적합한 방법을 선택하는 것도 문제해결능력
중요할까?
재료 제작에 사용되는 재료
도구 제작을 용이하게 해주는 장비, 부품
기술 설계능력, 노하우, 숙련도 …
결과 완성된 결과물
같은 재료, 도구를 사용하여 똑같은 물건을 만든다면??
물건을 제작하는 과정과 비교해 봅시다.
재료 프로그래밍 언어
도구 개발 툴, 라이브러리, 프레임워크, API, 알고리즘
등…
기술 개발경험, 숙련도, 문제해결능력
결과 프로그램
중요할까?
프로그래밍을 배우는 사람은 많아지고
진입장벽은 점점 더 낮아지고
수 많은 오픈 소스, 무료 강의, 무료 개발도구, 좋은 서적들, 구글링, Stack Overflow ...
배울 기술은 날로 늘어나고
새로운 언어, 프레임워크, 라이브러리, 개발 툴, 빌드 툴, …
또 각각 새로운 버전들…
중요할까?
결국 차이를 만드는 건 …
검색으로 얻거나, 단기간에 쌓기가 힘든 개인의 역량
다양하고 심도 있는 실제 개발 경험
무엇을 개발하더라도 적용할 수 있는 문제해결능력
게임으로 치자면?
캐릭터
개발자
능력치
문제해결능력
아이템
사용하는 기술
숙련도
그 기술에 대한 숙련도
중요할까?
주목 받는 문제해결능력
문제 해결하기
자신이 설계한 방법이 아래의 요건에 맞는지 생각해보아야 합니다.
여러 방법이 존재한다면, 가장 우선해야 할 조건에 따라 방법을 결정합니다.
속도 원 하 는 시 간 내 에 작 동 될 수
있는지
메모리 필요한 저장공간이 충분히 사용 가능한 수준인지
정확도 계산/처리 결과가 만족할 만큼 정확한지
효율성 코드 길이, 복잡도, 중복된 코드 등
대안 더 좋은, 더 조건에 맞는 방법은 없는지
문제 해결해보기
다양한 상황(문제)를 가정한 후, 효율적으로 해결할 수 있는 방법을 고민해봅시다.
문제를 보면서 같이 고민해보고, 자신의 생각과 비교해주세요.
해답 혹은 알고리즘 자체 보다는 아이디어를 떠올리는 방법에 초점을 맞춰주세요 
문제 해결해보기
당신은 ‘제비 뽑기’라는 게임을 제작하려고 합니다. 게임은 다음과 같은 규칙을 가지고
있습니다.
- 유저는 임의의 제비를 N개 선택합니다. 각 제비에는 자연수가 적혀있습니다.
- 제비들을 숫자가 보이지 않게 뒤집습니다.
- 그 후, 임의로 제비 한 장을 골라 숫자를 확인하고 다시 덮어두는 과정을 4번 반복했을
때, 이때 확인된 4개의 숫자의 합이 K가 될 수 있는 확률이 존재한다면 유저가 승리하게
됩니다.[예시]
예를 들어 N=5, K=12일 때, 유저가 선택한 제비가 아래와 같다면 …
1 3 6 2 9
* 문제 출처 : 프로그래밍 콘테스트 챌린징 1
차례로 6, 2, 2, 2가 적힌 제비를 확인할 경우, 합이 12가 된다.
이런 경우, 유저가 승리한다.
문제 해결해보기
[문제]
당신은 유저가 선택한 제비의 목록과 K가 주어졌을 때, 유저가 승리할 수 있는지 판단하는
함수를 만들기로 했습니다.
아래의 지시사항을 확인하여 함수를 구현해보세요.
* 문제 출처 : 프로그래밍 콘테스트 챌린징 1
[함수 정의]
// input : 뽑은 제비가 담긴 배열 numbers, 만들고자 하는 값 k
// return : 승리할 수 있는지 여부 T/F
boolean canWin(int[] numbers, int k);
[제한 사항]
- 𝑁 ≤ 10
- 𝐾 ≤ 40
문제 해결해보기
가장 간단하게 아래와 같은 방법을 떠올려 볼 수 있습니다.
numbers[0] + numbers[0] + numbers[0] + numbers[0] 는 K인가?
numbers[0] + numbers[0] + numbers[0] + numbers[1] 는 K인가?
numbers[0] + numbers[0] + numbers[0] + numbers[2] 는 K인가?
numbers[0] + numbers[0] + numbers[0] + numbers[n-1] 는
K인가?
numbers[0] + numbers[0] + numbers[1] + numbers[0] 는 K인가?
numbers[n-1] + numbers[n-1] + numbers[n-1] + numbers[n-1]
는 K인가?
…
…
모든 경우의 수를 확인해보고 하나라도 참이라면? 유저가 승리
문제 해결해보기
아래와 같이 구현할 수 있습니다. 이 방법은 효율적인 방법인지 고민해봅시다.
각 4중 for문에서 for문이 n번 순회하므로 약 𝑛4
번에 비례한 연산이
일어난다.
=> 시간 복잡도는 O(𝑛4
)이다.
문제 해결해보기
조금만 생각해보면, 모든 경우를 확인해 볼 필요는 없다는 점을 알 수 있습니다.
1. 제비가 더해진 순서가 중요할까?
- 예 : K=12일 때 {6, 2, 2, 2}, {2, 6, 2, 2}, {2, 2, 6, 2}, {2, 2, 2, 6}를 모두
확인할 필요는 없다.
𝑛𝑢𝑚 𝑎 + 𝑛𝑢𝑚 𝑏 + 𝑛𝑢𝑚 𝑐 + 𝑛𝑢𝑚 𝑑에 대해 𝑎 ≥ 𝑏 ≥ 𝑐 ≥ 𝑑인 경우만 검사해도 충분하다.
2. 1개 혹은 2개 혹은 3개의 숫자를 더했더니 K이상이 되었다면, 더 검사를 해볼 필요가
있을까?
numa ≥ K 이거나 num 𝑎 + numb ≥ K 이거나 num 𝑎 + numb + numc ≥ K 인 경우, 네 숫자의
합이 K가 될 확률은 존재하지 않는다.
- 예 : 현재까지 {6, 6}을 뽑았다. K=12라면 더 뽑아볼 필요가 없다.
문제 해결해보기
1
1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2
1 22 1 2 1 2 1
1 2 21
2
N=1, K=4이고 제비에 적힌 숫자가 {1, 2}인 경우 등장할 수 있는 경우의수를 모두
그려봅시다.
빨간색으로 칠해진 영역은 검사해보지 않아도 모든 경우의 수를 확인해 볼 수 있습니다
초록색으로 칠해진 영역은 합이 4가 될 경우가 없으므로, 확인해 볼 필요가 없습니다.
첫
번째
세
번째
두
번째
첫
번째
문제 해결해보기
4중 for문으로 시간 복잡도는 전과 같지만, 실제로는 𝑛4
보다 훨씬 적게 검사를
한다.
앞에서 정리한 내용을 구현하면 아래와 같다.
이처럼, 불필요한 계산과정을 건너뛰어 성능을 향상시키는 기법을 가지치기 라고
한다.
문제 해결해보기
[문제]
당신은 새로운 기능을 테스트하던 도중, 컴퓨터가 임의로 선택한 N개의 제비에 대해서
승리할 수 있는지 여부를 검사하는 과정에서 때때로 너무 많은 시간이 소요됨을
발견했습니다. 아래의 제약 사항에 맞추어 canWin() 함수를 수정해보세요
[제한 사항]
- 𝑁 ≤ 100
- 𝐾 ≤ 400
[함수 정의]
// input : 뽑은 제비가 담긴 배열 numbers, 만들고자 하는 값 k
// return : 승리할 수 있는지 여부 T/F
boolean canWin(int[] numbers, int k);
문제 해결해보기
우리는 3가지 숫자가 정해지면, 마지막 네 번째 숫자를 충분히 추정할 수 있습니다.
𝑛𝑢𝑚 𝑎 + 𝑛𝑢𝑚 𝑏 + 𝑛𝑢𝑚 𝑐 + 𝑛𝑢𝑚 𝑑 = K 라면 𝑛𝑢𝑚 𝑑 = K – (𝑛𝑢𝑚 𝑎 + 𝑛𝑢𝑚 𝑏 + 𝑛𝑢𝑚 𝑐)이기 때문
즉, 세 숫자를 정하고 𝑛𝑢𝑚 𝑑가 numbers[] 배열 내에 존재하는지 확인하면 된다.
실제로 성능이
개선되었을까요?
문제 해결해보기
3중 반복문의 시간복잡도는 𝑂 𝑛3
, 하지만 매 번 𝑛𝑢𝑚 𝑑를 찾기 위해서 𝑂(𝑛)의 탐색을 하므로
…
실제로는 𝑂 𝑛3
× 𝑛 = 𝑂(𝑛4
)으로 시간복잡도가 똑같다.
빠른 탐색이 필요하다? Binary Search?
하지만 Binary Search를 사용하기 위해서는 배열이 정렬이 되어있어야 한다…
배열을 정렬하는 데에는 또 그만큼 시간이 소모된다.
보통 대부분의 언어들에서는 Binary Search가 구현되어있다! 시간복잡도는 𝑂(log2 𝑛)
생각해보면 numbers[] 배열을 처음에 딱 1번만 정렬해두면, 계속 Binary Search를 사용할
수 있다.
- numbers배열을 정렬 - 𝑂(n ∙ log2 𝑛)
- 3중 for문을 돌며 binary search로 𝑛𝑢𝑚 𝑑를 numbers 배열 내에서 찾는다. - 𝑂(𝑛3
∙
log2 𝑛)그러므로, 전체 시간복잡도는 𝑂 n ∙ log2 𝑛 + 𝑛3
∙ log2 𝑛 = 𝑂 𝑛3
∙ log2 𝑛
문제 해결해보기
아래와 같이 구현할 수 있다.
- 내가 어떤 알고리즘을 사용할 수 있을지 생각해낼 수 있어야 한다.
- 각 알고리즘의 조건, 특징, 원리에 대한 이해를 하고 정확히 사용해야 한다.
문제 해결해보기
[문제]
당신은 선택하는 제비의 개수가 많아졌을 때의 수학적 확률에 대한 연구를 하기로
했습니다. 기존의 canWin() 함수를 사용하던 도중, N이 1,000정도로 커지게 되면 또 다시
상당한 시간이 소요됨을 알게 되었습니다. 아래의 제한사항을 참고하여 canWin() 함수를
조금 더 개선해봅시다.
[제한 사항]
- 𝑁 ≤ 1000
- 𝐾 ≤ 4000
[함수 정의]
// input : 뽑은 제비가 담긴 배열 numbers, 만들고자 하는 값 k
// return : 승리할 수 있는지 여부 T/F
boolean canWin(int[] numbers, int k);
문제 해결해보기
기존의 식 𝑛𝑢𝑚 𝑎 + 𝑛𝑢𝑚 𝑏 + 𝑛𝑢𝑚 𝑐 + 𝑛𝑢𝑚 𝑑 = 𝑘 에서 𝑛𝑢𝑚 𝑎 + 𝑛𝑢𝑚 𝑏 = 𝑋, 𝑛𝑢𝑚 𝑐 + 𝑛𝑢𝑚 𝑑 = 𝑌 로 두자.
X + 𝑌 = 𝑘이므로 마찬가지로 Y = 𝑘 − 𝑋와 같은 식을 유도할 수 있다.
즉 배열 numbers[]에서 두 수를 정해 그 합 X를 정하면 Y의 값을 계산할 수 있다.
이 때 두 수의 합이 Y가 되는 경우가 존재하는지 검사할 수 있다면 문제를 빠르게 해결할 수 있다.
가능한 X의 경우의 수를 모두 탐색 : O(𝑛2
)
계산된 Y를 만들 수 있는지 확인 : O(𝑛2
)
이 때 X, Y ∈ 𝑛𝑢𝑚𝑖 + 𝑛𝑢𝑚𝑗 0 ≤ 𝑖 ≤ 𝑗 ≤ 𝑛 − 1} 임을 알 수 있다.
numbers[] 배열의 두 원소의 합이 될 수 있는 모든 경우의 수를 미리 저장해둔다면?
문제 해결해보기
배열 twosum[] = 𝑛𝑢𝑚𝑖 + 𝑛𝑢𝑚𝑗 0 ≤ 𝑖 ≤ 𝑗 ≤ 𝑛 − 1} 이 있다고 가정해보자.
배열의 모든 원소를 하나씩 탐색한다.
- 모든 X의 경우의수를 판단할 수 있다.
twosum[] 배열이 정렬되어 있다면?
- twosum[] 배열 안에 Y가 존재하는지 Binary Search로 확인하면 된다.
1. twosum[] 배열을 생성한다 – O(𝑛2
)
2. twosum[] 배열을 정렬한다 - O(𝑛2
∙ log2 𝑛)
3. twosum[] 배열을 순회하며 X를 정한다. – O(𝑛2
)
- X를 통해 계산한 Y가 twosum[] 배열 안에 존재하는지 확인한다 – O(log2 𝑛)
시간복잡도는 O n2
+ n2
∙ log2 𝑛 + 𝑛2
∙ log2 𝑛 = 𝑂(𝑛2
∙ log2 𝑛)
문제 해결해보기
이를 직접 구현한 코드는 아래와 같다.
문제 해결해보기
[Key]
자주 계산해야 하는 값을 매번 계속하지 않고 어딘가에 저장해둔 후 바로 가져와 사용하면
시간을 절약할 수 있다. 단, 많은 메모리를 사용해야 한다는 단점이 있다.
이런 방법을 Memoization이라고 한다.
각 알고리즘의 시간복잡도 별로 근사 연산량을 비교해보자
𝒏 𝑂(𝑛2
∙ log2 𝑛) 𝑂(𝑛 𝟑
∙ log2 𝑛) 𝑂(𝑛 𝟒
)
10 300 3,000 10,000
100 60,000 6,000,000 100,000,000
1,000 9,000,000 9,000,000,000 1,000,000,000,000
알고리즘의 시간복잡도의 차이는 n의 크기가 클 수록 큰 성능 차이를 만들어낸다.
문제 해결해보기
당신은 요즘 유행하는 2D FPS 게임 ‘썩은어택’의 개발자입니다. 이 게임은 유저가 버튼을 누를 때 마다 임의의
N개 점에 총알들이 날아가게 됩니다. 2차원 평면상에 NPC가 그려진 영역 안에 총알이 위치할 경우 Hit Count가
1이 증가하게 됩니다.
각 NPC는 움직이지 않고 정지해 있으며, 각 NPC를 그리는 점들은 배열로 주어집니다. 당신은 유저가 총알들을
발사할 경우, 총알들과 NPC들간 충돌 체크에서 상당한 렉이 발생함을 알게 되었습니다.
한 NPC와 한 총알의 충돌을 체크하는 함수가 주어집니다. 이 함수를 사용하여 총 N개의 총알과 총 M개의
NPC에 대해 Hit Count를 최대한 빠르게 구하는 방법을 설계해보시오.
한 NPC는 보통 𝑝𝑖개의 점으로 이루어 져 있으며, 서로 영역이 겹치는 NPC는 없다.
맞은 총알
빗겨간 총알
문제 해결해보기
기존의 소스코드는 아래와 같이 작성되어 있다고 가정합시다.
위 알고리즘의 시간복잡도는 몇일까요?
한 NPC를 그리는 점의 개수를 𝑝𝑖라 할 때의 시간복잡도 𝑂(𝑛 ∙ 𝑚 ∙ 𝑝𝑖)
문제 해결해보기
아래의 예시를 봅시다. 총알 A에 비하여 총알 B는 눈으로 보기에 굳이 충돌 검사를 할
필요가 없어 보입니다. 이렇게 멀리 떨어져있는 점과 NPC는 충돌검사를 하지 않는다면
시간을 절약할 수 있을 것 같습니다. 즉 가지치기가 가능해 보입니다.
B
A
어떻게 하면 총알 B 같은 경우를 빠르게 가지치기 할 수 있을까요?
문제 해결해보기
NPC를 완전히 포함하는 최소의 직사각형이 있다고 가정해봅시다.
B
A
저 직사각형 밖의 점에 대해 충돌검사를 할 필요가 있을까요?
한 점이 NPC의 영역에 포함되는지 검사하는 데에 필요한 시간복잡도 : O(𝑝𝑖)
한 점이 직사각형에 포함되는지 검사하는 데에 필요한 시간복잡도 : O(1)
즉, 답이 될 가능성이 없는 점(사각형 밖의 점)에 대해선 빠르게 검사가 가능합니다.
문제 해결해보기
한 NPC을 포함하는 직사각형을 찾는 방법 : O(𝑝𝑖)
하지만, 한 NPC에 대해 직사각형을 한번 구해둔 후 저장해두면 모든 점과의 충돌 검사에
사용할 수 있다. 즉, 직사각형의 좌표를 Memoization을 해둘 수 있다.
문제 해결해보기
또한 …
두 NPC는 서로 영역을 공유하지 않습니다.
즉, 한 총알은 두 개 이상의 NPC와 충돌할 리 없습니다.
이미 어딘가에 충돌한 적이 있는 총알이라면 충돌검사를 할 필요 없습니다.
해당 총알이 NPC에 충돌한 적이 있는지 여부를 Memoization한다면?
이 처럼 같은 기능을 구현하더라도, 다양한 방법으로 최적화 할 수 있는 방법이 존재합니다.
이렇게 많은 방법들 중 현재 가장 적합한 방법을 찾아낼 수 있어야 합니다
문제해결능력 기르기
하나 많이 고민하고, 많이 코딩 해보기
어떻게 구현할까?
다른 방법은 없을까?내 방법이 정확한가?
코드를 더 간결하게
작성할 수 있을까?
코딩을 하기 전 다양한 방법을 머릿속으로 생각해보기
코딩을 하면서도 더 좋은 방법이 없는지 계속 고민하기
경험적으로 쌓이는 코딩센스도 중요합니다!
문제해결능력 기르기
둘 정확히 이해하고 ‘잘’ 활용하기
수학, 알고리즘, 라이브러리, 프레임워크, 검색 까지… 나를 도와줄 수 있는 모든 것들
무엇을, 언제, 어떻게 활용할지를 결정하는 것도 문제해결능력
‘얼마나 많이 아는가’ 보다 중요한 것은 ‘얼마나 잘 활용할 수 있는가’
알고리즘 라이브러리 지식창고
단순히 ‘안다’, ‘사용해봤다’에 만족하지 말고 정확히 이해하고 활용해봅시다.
문제해결능력 기르기
셋 다른 사람의 아이디어 배우기
사람마다 지식도, 경험도, 아이디어도 모두 다를 수 밖에 없다.
같은 것을 구현한 다른 사람의 코드를 보고 자신의 방법과 비교해보자.
모르는 것은 지나치지 말고 물어서라도 알고 넘어가기
다른 사람의 아이디어를 배울 수 있는 방법은 수 없이 많다.
문제해결능력 기르기
하나 많이 고민하고, 많이 코딩 해보기
둘 정확히 이해하고 ‘잘’ 활용하기
셋 다른 사람의 아이디어 배우기
요약해보면 …
너무나 당연한 내용이지만 실천하기는 쉽지가 않다!
문제해결능력 기르기
추천하는 방법 프로그래밍문제 풀어보기
원하는 언어로 다양한 프로그래밍 연습을 할 수 있다.
다양한 상황, 제한사항에 따라 다양한 방법을 고민해볼 수 있다.
다른 사람의 코드를 보거나 검색해보면서 다양한 스킬을 익힐 수 있다.
지적유희?
다양한 문제를 풀어보면 어떤 점이 좋을까?
다양한 문제를 프로그래밍으로 해결하고 소스코드를 제출하는 방식
다양한 상황, 제약사항을 가정하고 가장 적합한 방법을 찾아내야 한다.
설계된 방법을 정확히 구현해야 한다.
문제해결능력 기르기
프로그래밍 문제를 풀어볼 수 있는 다양한 사이트들
Lavida.us
친구와 코딩 배틀을 할 수도 있고
실제로 다양한 대회도 열리고 있다
세 줄 요약
문제해결능력이란 문제를 정확히 이해하고 가장 적합한 방법을 찾고 구현하는
능력
어떤 개발을 하게 되더라도 프로그래밍의 질적 차이를 만든다.
다양한 프로그래밍 경험과 문제해결능력이 시너지를 이루는 좋은 개발자가 됩니다.

QnA
질문 받습니다!
URLs
Lavida Online Judge
- http://lavida.us
Baekjoon Online Judge
- http://acmicpc.net
Dovelet
- http://dovelet.com
Algospot Online Judge
- http://algospot.com
Codeforces
- http://codeforces.com
TopCoder
- http://topcoder.com/tc
Google Code Jam
- http://code.google.com/codejam
Fin
감사합니다. 

Contenu connexe

Tendances

[D2 CAMPUS] 숭실대 SCCC 프로그래밍 경시대회 문제
[D2 CAMPUS] 숭실대 SCCC 프로그래밍 경시대회 문제[D2 CAMPUS] 숭실대 SCCC 프로그래밍 경시대회 문제
[D2 CAMPUS] 숭실대 SCCC 프로그래밍 경시대회 문제NAVER D2
 
[D2 CAMPUS] 2016 한양대학교 프로그래밍 경시대회 문제풀이
[D2 CAMPUS] 2016 한양대학교 프로그래밍 경시대회 문제풀이[D2 CAMPUS] 2016 한양대학교 프로그래밍 경시대회 문제풀이
[D2 CAMPUS] 2016 한양대학교 프로그래밍 경시대회 문제풀이NAVER D2
 
[KAIST - RUN] 프로그래밍 경진대회 문제
[KAIST - RUN] 프로그래밍 경진대회 문제[KAIST - RUN] 프로그래밍 경진대회 문제
[KAIST - RUN] 프로그래밍 경진대회 문제NAVER D2
 
2015 한양대학교 프로그래밍 경시대회 - beginner division
2015 한양대학교 프로그래밍 경시대회 - beginner division2015 한양대학교 프로그래밍 경시대회 - beginner division
2015 한양대학교 프로그래밍 경시대회 - beginner divisionNAVER D2
 
[한양대 aloha] 프로그래밍 경진대회 문제_advanced part
[한양대 aloha] 프로그래밍 경진대회 문제_advanced part[한양대 aloha] 프로그래밍 경진대회 문제_advanced part
[한양대 aloha] 프로그래밍 경진대회 문제_advanced partNAVER D2
 
[고려대 ALPS&ALKOR] 프로그래밍 경진대회 문제
[고려대 ALPS&ALKOR] 프로그래밍 경진대회 문제[고려대 ALPS&ALKOR] 프로그래밍 경진대회 문제
[고려대 ALPS&ALKOR] 프로그래밍 경진대회 문제NAVER D2
 
[한양대 aloha] 프로그래밍 경진대회 문제_Beginner part
[한양대 aloha] 프로그래밍 경진대회 문제_Beginner part[한양대 aloha] 프로그래밍 경진대회 문제_Beginner part
[한양대 aloha] 프로그래밍 경진대회 문제_Beginner partNAVER D2
 
HI-ARC PS 102 Brute Force
HI-ARC PS 102 Brute ForceHI-ARC PS 102 Brute Force
HI-ARC PS 102 Brute ForceJae-yeol Lee
 
한양대학교 ALOHA - 봄내전대회_C언어반
 한양대학교 ALOHA - 봄내전대회_C언어반 한양대학교 ALOHA - 봄내전대회_C언어반
한양대학교 ALOHA - 봄내전대회_C언어반NAVER D2
 
Backtracking [ICPC Sinchon]
Backtracking [ICPC Sinchon]Backtracking [ICPC Sinchon]
Backtracking [ICPC Sinchon]Jae-yeol Lee
 
[SHAKE] 경인지역 6개연합 프로그래밍 경시대회 - 본선문제
[SHAKE] 경인지역 6개연합 프로그래밍 경시대회 - 본선문제[SHAKE] 경인지역 6개연합 프로그래밍 경시대회 - 본선문제
[SHAKE] 경인지역 6개연합 프로그래밍 경시대회 - 본선문제NAVER D2
 
한양대학교 ALOHA - 봄내전대회_알고리즘반
한양대학교 ALOHA - 봄내전대회_알고리즘반한양대학교 ALOHA - 봄내전대회_알고리즘반
한양대학교 ALOHA - 봄내전대회_알고리즘반NAVER D2
 
2021 1학기 정기 세미나 6주차
2021 1학기 정기 세미나 6주차2021 1학기 정기 세미나 6주차
2021 1학기 정기 세미나 6주차Moonki Choi
 
[D2CAMPUS] Algorithm tips - ALGOS
[D2CAMPUS] Algorithm tips - ALGOS[D2CAMPUS] Algorithm tips - ALGOS
[D2CAMPUS] Algorithm tips - ALGOSNAVER D2
 
HI-ARC Number Theory
HI-ARC Number TheoryHI-ARC Number Theory
HI-ARC Number TheoryJae-yeol Lee
 
2012 Dm C3 03
2012 Dm C3 032012 Dm C3 03
2012 Dm C3 03chl132435
 
이산치3보고서
이산치3보고서이산치3보고서
이산치3보고서KimChangHoen
 
SHAKE - 경기 남부 4개대학 연합 프로그래밍 경시대회 본선문제
SHAKE - 경기 남부 4개대학 연합 프로그래밍 경시대회 본선문제SHAKE - 경기 남부 4개대학 연합 프로그래밍 경시대회 본선문제
SHAKE - 경기 남부 4개대학 연합 프로그래밍 경시대회 본선문제NAVER D2
 
[SHAKE] 경인지역 6개연합 프로그래밍 경시대회 - 예선문제(아주대)
[SHAKE] 경인지역 6개연합 프로그래밍 경시대회 - 예선문제(아주대)[SHAKE] 경인지역 6개연합 프로그래밍 경시대회 - 예선문제(아주대)
[SHAKE] 경인지역 6개연합 프로그래밍 경시대회 - 예선문제(아주대)NAVER D2
 

Tendances (20)

[D2 CAMPUS] 숭실대 SCCC 프로그래밍 경시대회 문제
[D2 CAMPUS] 숭실대 SCCC 프로그래밍 경시대회 문제[D2 CAMPUS] 숭실대 SCCC 프로그래밍 경시대회 문제
[D2 CAMPUS] 숭실대 SCCC 프로그래밍 경시대회 문제
 
[D2 CAMPUS] 2016 한양대학교 프로그래밍 경시대회 문제풀이
[D2 CAMPUS] 2016 한양대학교 프로그래밍 경시대회 문제풀이[D2 CAMPUS] 2016 한양대학교 프로그래밍 경시대회 문제풀이
[D2 CAMPUS] 2016 한양대학교 프로그래밍 경시대회 문제풀이
 
[KAIST - RUN] 프로그래밍 경진대회 문제
[KAIST - RUN] 프로그래밍 경진대회 문제[KAIST - RUN] 프로그래밍 경진대회 문제
[KAIST - RUN] 프로그래밍 경진대회 문제
 
2015 한양대학교 프로그래밍 경시대회 - beginner division
2015 한양대학교 프로그래밍 경시대회 - beginner division2015 한양대학교 프로그래밍 경시대회 - beginner division
2015 한양대학교 프로그래밍 경시대회 - beginner division
 
[한양대 aloha] 프로그래밍 경진대회 문제_advanced part
[한양대 aloha] 프로그래밍 경진대회 문제_advanced part[한양대 aloha] 프로그래밍 경진대회 문제_advanced part
[한양대 aloha] 프로그래밍 경진대회 문제_advanced part
 
[고려대 ALPS&ALKOR] 프로그래밍 경진대회 문제
[고려대 ALPS&ALKOR] 프로그래밍 경진대회 문제[고려대 ALPS&ALKOR] 프로그래밍 경진대회 문제
[고려대 ALPS&ALKOR] 프로그래밍 경진대회 문제
 
[한양대 aloha] 프로그래밍 경진대회 문제_Beginner part
[한양대 aloha] 프로그래밍 경진대회 문제_Beginner part[한양대 aloha] 프로그래밍 경진대회 문제_Beginner part
[한양대 aloha] 프로그래밍 경진대회 문제_Beginner part
 
HI-ARC PS 101
HI-ARC PS 101HI-ARC PS 101
HI-ARC PS 101
 
HI-ARC PS 102 Brute Force
HI-ARC PS 102 Brute ForceHI-ARC PS 102 Brute Force
HI-ARC PS 102 Brute Force
 
한양대학교 ALOHA - 봄내전대회_C언어반
 한양대학교 ALOHA - 봄내전대회_C언어반 한양대학교 ALOHA - 봄내전대회_C언어반
한양대학교 ALOHA - 봄내전대회_C언어반
 
Backtracking [ICPC Sinchon]
Backtracking [ICPC Sinchon]Backtracking [ICPC Sinchon]
Backtracking [ICPC Sinchon]
 
[SHAKE] 경인지역 6개연합 프로그래밍 경시대회 - 본선문제
[SHAKE] 경인지역 6개연합 프로그래밍 경시대회 - 본선문제[SHAKE] 경인지역 6개연합 프로그래밍 경시대회 - 본선문제
[SHAKE] 경인지역 6개연합 프로그래밍 경시대회 - 본선문제
 
한양대학교 ALOHA - 봄내전대회_알고리즘반
한양대학교 ALOHA - 봄내전대회_알고리즘반한양대학교 ALOHA - 봄내전대회_알고리즘반
한양대학교 ALOHA - 봄내전대회_알고리즘반
 
2021 1학기 정기 세미나 6주차
2021 1학기 정기 세미나 6주차2021 1학기 정기 세미나 6주차
2021 1학기 정기 세미나 6주차
 
[D2CAMPUS] Algorithm tips - ALGOS
[D2CAMPUS] Algorithm tips - ALGOS[D2CAMPUS] Algorithm tips - ALGOS
[D2CAMPUS] Algorithm tips - ALGOS
 
HI-ARC Number Theory
HI-ARC Number TheoryHI-ARC Number Theory
HI-ARC Number Theory
 
2012 Dm C3 03
2012 Dm C3 032012 Dm C3 03
2012 Dm C3 03
 
이산치3보고서
이산치3보고서이산치3보고서
이산치3보고서
 
SHAKE - 경기 남부 4개대학 연합 프로그래밍 경시대회 본선문제
SHAKE - 경기 남부 4개대학 연합 프로그래밍 경시대회 본선문제SHAKE - 경기 남부 4개대학 연합 프로그래밍 경시대회 본선문제
SHAKE - 경기 남부 4개대학 연합 프로그래밍 경시대회 본선문제
 
[SHAKE] 경인지역 6개연합 프로그래밍 경시대회 - 예선문제(아주대)
[SHAKE] 경인지역 6개연합 프로그래밍 경시대회 - 예선문제(아주대)[SHAKE] 경인지역 6개연합 프로그래밍 경시대회 - 예선문제(아주대)
[SHAKE] 경인지역 6개연합 프로그래밍 경시대회 - 예선문제(아주대)
 

En vedette

집단 지성 (Programming collective intelligence) 스터디: Chapter 4 - Searching & Ranking
집단 지성 (Programming collective intelligence) 스터디: Chapter 4 - Searching & Ranking집단 지성 (Programming collective intelligence) 스터디: Chapter 4 - Searching & Ranking
집단 지성 (Programming collective intelligence) 스터디: Chapter 4 - Searching & RankingIan Choi
 
Mesos on coreOS
Mesos on coreOSMesos on coreOS
Mesos on coreOS충섭 김
 
Amazon EC2 Container Service in Action
Amazon EC2 Container Service in ActionAmazon EC2 Container Service in Action
Amazon EC2 Container Service in ActionRemotty
 
나는 어떻게 알고리즘을 공부했을까? + 신기한 방법으로 문제 풀어보기
나는 어떻게 알고리즘을 공부했을까? + 신기한 방법으로 문제 풀어보기나는 어떻게 알고리즘을 공부했을까? + 신기한 방법으로 문제 풀어보기
나는 어떻게 알고리즘을 공부했을까? + 신기한 방법으로 문제 풀어보기Baekjoon Choi
 
RancherOS Introduction
RancherOS IntroductionRancherOS Introduction
RancherOS IntroductionRemotty
 
형태소 분석기를 적용한 elasticsearch 운영
형태소 분석기를 적용한 elasticsearch 운영형태소 분석기를 적용한 elasticsearch 운영
형태소 분석기를 적용한 elasticsearch 운영창훈 정
 
1.openseminar
1.openseminar1.openseminar
1.openseminarNAVER D2
 
네이버 오픈세미나 백엔드_아키텍쳐
네이버 오픈세미나 백엔드_아키텍쳐네이버 오픈세미나 백엔드_아키텍쳐
네이버 오픈세미나 백엔드_아키텍쳐NAVER D2
 
5.yobi를 활용한 개발자 협업 및 배포 프로세스
5.yobi를 활용한 개발자 협업 및 배포 프로세스5.yobi를 활용한 개발자 협업 및 배포 프로세스
5.yobi를 활용한 개발자 협업 및 배포 프로세스NAVER D2
 
2.네이버 프론트엔드 김지태
2.네이버 프론트엔드 김지태2.네이버 프론트엔드 김지태
2.네이버 프론트엔드 김지태NAVER D2
 

En vedette (13)

집단 지성 (Programming collective intelligence) 스터디: Chapter 4 - Searching & Ranking
집단 지성 (Programming collective intelligence) 스터디: Chapter 4 - Searching & Ranking집단 지성 (Programming collective intelligence) 스터디: Chapter 4 - Searching & Ranking
집단 지성 (Programming collective intelligence) 스터디: Chapter 4 - Searching & Ranking
 
Mesos on coreOS
Mesos on coreOSMesos on coreOS
Mesos on coreOS
 
Amazon EC2 Container Service in Action
Amazon EC2 Container Service in ActionAmazon EC2 Container Service in Action
Amazon EC2 Container Service in Action
 
나는 어떻게 알고리즘을 공부했을까? + 신기한 방법으로 문제 풀어보기
나는 어떻게 알고리즘을 공부했을까? + 신기한 방법으로 문제 풀어보기나는 어떻게 알고리즘을 공부했을까? + 신기한 방법으로 문제 풀어보기
나는 어떻게 알고리즘을 공부했을까? + 신기한 방법으로 문제 풀어보기
 
Docker orchestration
Docker orchestrationDocker orchestration
Docker orchestration
 
RancherOS Introduction
RancherOS IntroductionRancherOS Introduction
RancherOS Introduction
 
형태소 분석기를 적용한 elasticsearch 운영
형태소 분석기를 적용한 elasticsearch 운영형태소 분석기를 적용한 elasticsearch 운영
형태소 분석기를 적용한 elasticsearch 운영
 
1.openseminar
1.openseminar1.openseminar
1.openseminar
 
네이버 오픈세미나 백엔드_아키텍쳐
네이버 오픈세미나 백엔드_아키텍쳐네이버 오픈세미나 백엔드_아키텍쳐
네이버 오픈세미나 백엔드_아키텍쳐
 
Arcus
ArcusArcus
Arcus
 
5.yobi를 활용한 개발자 협업 및 배포 프로세스
5.yobi를 활용한 개발자 협업 및 배포 프로세스5.yobi를 활용한 개발자 협업 및 배포 프로세스
5.yobi를 활용한 개발자 협업 및 배포 프로세스
 
Docker toolbox
Docker toolboxDocker toolbox
Docker toolbox
 
2.네이버 프론트엔드 김지태
2.네이버 프론트엔드 김지태2.네이버 프론트엔드 김지태
2.네이버 프론트엔드 김지태
 

Similaire à 세미나

언플러그드 활동의 이론과 실제(Unplugged Activity / Computing)
언플러그드 활동의 이론과 실제(Unplugged Activity / Computing)언플러그드 활동의 이론과 실제(Unplugged Activity / Computing)
언플러그드 활동의 이론과 실제(Unplugged Activity / Computing)Sangsu Song
 
코드와 실습으로 이해하는 인공지능
코드와 실습으로 이해하는 인공지능코드와 실습으로 이해하는 인공지능
코드와 실습으로 이해하는 인공지능도형 임
 
두 번째 startlink.live: 김재홍 (xhark) - 알고리즘 문제 출제 전략
두 번째 startlink.live: 김재홍 (xhark) - 알고리즘 문제 출제 전략두 번째 startlink.live: 김재홍 (xhark) - 알고리즘 문제 출제 전략
두 번째 startlink.live: 김재홍 (xhark) - 알고리즘 문제 출제 전략Startlink
 
Ai 그까이거
Ai 그까이거Ai 그까이거
Ai 그까이거도형 임
 
[소프트웨어교육] 알고리즘 교사 연수 자료
[소프트웨어교육] 알고리즘 교사 연수 자료[소프트웨어교육] 알고리즘 교사 연수 자료
[소프트웨어교육] 알고리즘 교사 연수 자료Sangsu Song
 
생각하는 프로그래밍 1부
생각하는 프로그래밍 1부생각하는 프로그래밍 1부
생각하는 프로그래밍 1부sj k
 
Coding interview
Coding interviewCoding interview
Coding interviewSoohan Ahn
 
알고리즘 연합캠프 세미나 1-C (알고리즘 설계와 모델링 및 수학)
알고리즘 연합캠프 세미나 1-C (알고리즘 설계와 모델링 및 수학)알고리즘 연합캠프 세미나 1-C (알고리즘 설계와 모델링 및 수학)
알고리즘 연합캠프 세미나 1-C (알고리즘 설계와 모델링 및 수학)HYUNJEONG KIM
 
자바로 Mnist 구현하고_스프링웹서버붙이기
자바로 Mnist 구현하고_스프링웹서버붙이기자바로 Mnist 구현하고_스프링웹서버붙이기
자바로 Mnist 구현하고_스프링웹서버붙이기라한사 아
 
숫자 구분자 처리 (Digit group separators)
숫자 구분자 처리 (Digit group separators)숫자 구분자 처리 (Digit group separators)
숫자 구분자 처리 (Digit group separators)중선 곽
 
소프트웨어 교육 실습
소프트웨어 교육 실습소프트웨어 교육 실습
소프트웨어 교육 실습Jaehwi Alice Kim
 
Chapter 11 Practical Methodology
Chapter 11 Practical MethodologyChapter 11 Practical Methodology
Chapter 11 Practical MethodologyKyeongUkJang
 
프로그램 기초
프로그램 기초프로그램 기초
프로그램 기초Minsuk Lee
 
코딩테스트 합격자 되기 연말강의자료(프로그래머스 콜라보)
코딩테스트 합격자 되기 연말강의자료(프로그래머스 콜라보)코딩테스트 합격자 되기 연말강의자료(프로그래머스 콜라보)
코딩테스트 합격자 되기 연말강의자료(프로그래머스 콜라보)ultrasuperrok
 
국민대학교 컴퓨터프로그래밍
국민대학교 컴퓨터프로그래밍국민대학교 컴퓨터프로그래밍
국민대학교 컴퓨터프로그래밍Minsuk Lee
 
Study_1st_sineunjj
Study_1st_sineunjjStudy_1st_sineunjj
Study_1st_sineunjjssuser4913c5
 
2012 Dm A0 01 Pdf
2012 Dm A0 01 Pdf2012 Dm A0 01 Pdf
2012 Dm A0 01 Pdfjinwookhong
 
2012 Dm A0 01 Pdf
2012 Dm A0 01 Pdf2012 Dm A0 01 Pdf
2012 Dm A0 01 Pdfkd19h
 
네이버 SW교육 교사 연수자료_ 송상수
네이버 SW교육 교사 연수자료_ 송상수네이버 SW교육 교사 연수자료_ 송상수
네이버 SW교육 교사 연수자료_ 송상수Sangsu Song
 
코딩테트2205-kucc-220508145530-8015b5d7.pdf
코딩테트2205-kucc-220508145530-8015b5d7.pdf코딩테트2205-kucc-220508145530-8015b5d7.pdf
코딩테트2205-kucc-220508145530-8015b5d7.pdfssuser597fbd
 

Similaire à 세미나 (20)

언플러그드 활동의 이론과 실제(Unplugged Activity / Computing)
언플러그드 활동의 이론과 실제(Unplugged Activity / Computing)언플러그드 활동의 이론과 실제(Unplugged Activity / Computing)
언플러그드 활동의 이론과 실제(Unplugged Activity / Computing)
 
코드와 실습으로 이해하는 인공지능
코드와 실습으로 이해하는 인공지능코드와 실습으로 이해하는 인공지능
코드와 실습으로 이해하는 인공지능
 
두 번째 startlink.live: 김재홍 (xhark) - 알고리즘 문제 출제 전략
두 번째 startlink.live: 김재홍 (xhark) - 알고리즘 문제 출제 전략두 번째 startlink.live: 김재홍 (xhark) - 알고리즘 문제 출제 전략
두 번째 startlink.live: 김재홍 (xhark) - 알고리즘 문제 출제 전략
 
Ai 그까이거
Ai 그까이거Ai 그까이거
Ai 그까이거
 
[소프트웨어교육] 알고리즘 교사 연수 자료
[소프트웨어교육] 알고리즘 교사 연수 자료[소프트웨어교육] 알고리즘 교사 연수 자료
[소프트웨어교육] 알고리즘 교사 연수 자료
 
생각하는 프로그래밍 1부
생각하는 프로그래밍 1부생각하는 프로그래밍 1부
생각하는 프로그래밍 1부
 
Coding interview
Coding interviewCoding interview
Coding interview
 
알고리즘 연합캠프 세미나 1-C (알고리즘 설계와 모델링 및 수학)
알고리즘 연합캠프 세미나 1-C (알고리즘 설계와 모델링 및 수학)알고리즘 연합캠프 세미나 1-C (알고리즘 설계와 모델링 및 수학)
알고리즘 연합캠프 세미나 1-C (알고리즘 설계와 모델링 및 수학)
 
자바로 Mnist 구현하고_스프링웹서버붙이기
자바로 Mnist 구현하고_스프링웹서버붙이기자바로 Mnist 구현하고_스프링웹서버붙이기
자바로 Mnist 구현하고_스프링웹서버붙이기
 
숫자 구분자 처리 (Digit group separators)
숫자 구분자 처리 (Digit group separators)숫자 구분자 처리 (Digit group separators)
숫자 구분자 처리 (Digit group separators)
 
소프트웨어 교육 실습
소프트웨어 교육 실습소프트웨어 교육 실습
소프트웨어 교육 실습
 
Chapter 11 Practical Methodology
Chapter 11 Practical MethodologyChapter 11 Practical Methodology
Chapter 11 Practical Methodology
 
프로그램 기초
프로그램 기초프로그램 기초
프로그램 기초
 
코딩테스트 합격자 되기 연말강의자료(프로그래머스 콜라보)
코딩테스트 합격자 되기 연말강의자료(프로그래머스 콜라보)코딩테스트 합격자 되기 연말강의자료(프로그래머스 콜라보)
코딩테스트 합격자 되기 연말강의자료(프로그래머스 콜라보)
 
국민대학교 컴퓨터프로그래밍
국민대학교 컴퓨터프로그래밍국민대학교 컴퓨터프로그래밍
국민대학교 컴퓨터프로그래밍
 
Study_1st_sineunjj
Study_1st_sineunjjStudy_1st_sineunjj
Study_1st_sineunjj
 
2012 Dm A0 01 Pdf
2012 Dm A0 01 Pdf2012 Dm A0 01 Pdf
2012 Dm A0 01 Pdf
 
2012 Dm A0 01 Pdf
2012 Dm A0 01 Pdf2012 Dm A0 01 Pdf
2012 Dm A0 01 Pdf
 
네이버 SW교육 교사 연수자료_ 송상수
네이버 SW교육 교사 연수자료_ 송상수네이버 SW교육 교사 연수자료_ 송상수
네이버 SW교육 교사 연수자료_ 송상수
 
코딩테트2205-kucc-220508145530-8015b5d7.pdf
코딩테트2205-kucc-220508145530-8015b5d7.pdf코딩테트2205-kucc-220508145530-8015b5d7.pdf
코딩테트2205-kucc-220508145530-8015b5d7.pdf
 

세미나

  • 2. Presenter Dongyi Kim 아주대학교 컴퓨터공학과 재학 알고리즘 연구 동아리 ANSI 활동 가라지스토리 안드로이드 개발자 (2014) ICTK 보안연구원 (2014 ~ 2015) 2013 ACM ICPC Asia-Daejeon Regional 13th placed 2012 ACM ICPC Asia-Daejeon Regional 18th placed 2013 전국 대학생 프로그래밍 경시대회 동상 정보올림피아드 지역본선 은상 정보올림피아드 지역본선 은상 정보올림피아드 지역본선 은상 정보올림피아드 지역본선 은상 정보올림피아드 지역본선 은상
  • 3. Contents 알고리즘? 문제해결능력? 무엇인지, 왜 중요한지에 대해 실제로 문제를 해결해보기 실제 상황을 가정해서 적용해보기 훈련해볼 수 있는 방법 평소에 문제해결능력을 훈련할 수 있는 방법
  • 4. 문제해결능력 Q. 아래에서 해당하는 사항이 있나요? - 프로그래밍을 공부했지만, 스스로 코딩을 하기는 힘들다. - 다른 사람들에 비해 내가 짠 프로그램은 코드가 길고 성능도 좋지 않다. - 기능이 조금만 복잡해져도 키보드에 손도 못 댈 것 같다. - 알고리즘, 자료구조, 계산이론 … 이런 것들을 대체 왜 배우는지 모르겠다. - 개발이 단순 반복 작업처럼 느껴지고 지루하다. A. 해당하는 사항이 있다면? 문제해결능력을 길러야 할 때 대상 프로그래밍을 공부했고 알고리즘과 자료구조를 공부하고 있는 학생
  • 5. 문제해결능력 문제 무엇인가를 프로그래밍을 통해 계산, 구현, 개선해야 하는 상황 해결 속도, 효율, 정확성 등을 고려하여 문제를 해결할 가장 적합한 방법을 찾고 구현하는 것 문제해결능력 = 분석능력 + 사고력 + 지식 + 판단력 + 아이디어 + … + 알고리즘
  • 6. 문제해결과정 분석 요구사항, 제한사항을 확인하여 무엇을 구현할 것인가에 대한 결정 설계 다양한 사항을 고려하여 최적의 방법을 설계 구현 설계된 사항대로 정확하고 간결하게 구현 프로그래밍 언어 프로그램설계분석 구현
  • 7. 알고리즘이란? 알고리즘 어떠한 문제를 효율적으로 해결하기 위해 설계된 방법 자료구조 자료들을 특정한 목적에 맞게 효율적으로 저장/가공할 수 있도록 설계된 방법 즉, 알고리즘과 자료구조는 어떠한 문제를 해결하기 위해 설계된 방법 - 이미 설계되어 있는 알고리즘을 활용하여 문제를 해결할 수 있다. - 많이 알고 있을 수록 문제해결 시 선택의 폭이 넓어진다. - 알고리즘에 대한 충분한 이해를 하고 있다면, 이를 수정하거나 아이디어를 빌려 활용할 수 있다. 다양한 알고리즘을 공부하는 것은 문제해결능력을 기르는 효과적인 방법
  • 8. 알고리즘이란? 방법 속도 메모리 정확도 구현난이도 A 느리다 조금 사용 정확하다 매우 단순하다 B 빠르다 많이 사용 정확하다 보통이다 C 빠르다 조금 사용 보장못함 매우 단순하다 A2 꾀 빠르다 조금 사용 정확하다 단순하다 B2 엄청 빠르다 엄청 많이 사용 정확하다 많이 복잡하다 C2 엄청 빠르다 조금 사용 거의 근사 한다 단순하다 당신은 어떤 문제에 대해 다음과 같은 세 해결 방법을 떠올렸습니다. ‘갑 알고리즘’의 아이디어를 방법 A에 응용했더니 아래와 같이 개선 되었다. ‘을 자료구조’를 방법 B와 함께 사용했더니 아래와 같이 개선되었다. ‘병 알고리즘’을 방법 C에 활용했더니 아래와 같이 개선되었다. 이처럼 다양한 알고리즘과 아이디어에 의해 같은 문제에 대해서 다양한 해결 방법이 나올 수 있습니다. 또한, 여러 방법 중 현재 가장 적합한 방법을 선택하는 것도 문제해결능력
  • 9. 중요할까? 재료 제작에 사용되는 재료 도구 제작을 용이하게 해주는 장비, 부품 기술 설계능력, 노하우, 숙련도 … 결과 완성된 결과물 같은 재료, 도구를 사용하여 똑같은 물건을 만든다면?? 물건을 제작하는 과정과 비교해 봅시다. 재료 프로그래밍 언어 도구 개발 툴, 라이브러리, 프레임워크, API, 알고리즘 등… 기술 개발경험, 숙련도, 문제해결능력 결과 프로그램
  • 10. 중요할까? 프로그래밍을 배우는 사람은 많아지고 진입장벽은 점점 더 낮아지고 수 많은 오픈 소스, 무료 강의, 무료 개발도구, 좋은 서적들, 구글링, Stack Overflow ... 배울 기술은 날로 늘어나고 새로운 언어, 프레임워크, 라이브러리, 개발 툴, 빌드 툴, … 또 각각 새로운 버전들…
  • 11. 중요할까? 결국 차이를 만드는 건 … 검색으로 얻거나, 단기간에 쌓기가 힘든 개인의 역량 다양하고 심도 있는 실제 개발 경험 무엇을 개발하더라도 적용할 수 있는 문제해결능력 게임으로 치자면? 캐릭터 개발자 능력치 문제해결능력 아이템 사용하는 기술 숙련도 그 기술에 대한 숙련도
  • 13. 문제 해결하기 자신이 설계한 방법이 아래의 요건에 맞는지 생각해보아야 합니다. 여러 방법이 존재한다면, 가장 우선해야 할 조건에 따라 방법을 결정합니다. 속도 원 하 는 시 간 내 에 작 동 될 수 있는지 메모리 필요한 저장공간이 충분히 사용 가능한 수준인지 정확도 계산/처리 결과가 만족할 만큼 정확한지 효율성 코드 길이, 복잡도, 중복된 코드 등 대안 더 좋은, 더 조건에 맞는 방법은 없는지
  • 14. 문제 해결해보기 다양한 상황(문제)를 가정한 후, 효율적으로 해결할 수 있는 방법을 고민해봅시다. 문제를 보면서 같이 고민해보고, 자신의 생각과 비교해주세요. 해답 혹은 알고리즘 자체 보다는 아이디어를 떠올리는 방법에 초점을 맞춰주세요 
  • 15. 문제 해결해보기 당신은 ‘제비 뽑기’라는 게임을 제작하려고 합니다. 게임은 다음과 같은 규칙을 가지고 있습니다. - 유저는 임의의 제비를 N개 선택합니다. 각 제비에는 자연수가 적혀있습니다. - 제비들을 숫자가 보이지 않게 뒤집습니다. - 그 후, 임의로 제비 한 장을 골라 숫자를 확인하고 다시 덮어두는 과정을 4번 반복했을 때, 이때 확인된 4개의 숫자의 합이 K가 될 수 있는 확률이 존재한다면 유저가 승리하게 됩니다.[예시] 예를 들어 N=5, K=12일 때, 유저가 선택한 제비가 아래와 같다면 … 1 3 6 2 9 * 문제 출처 : 프로그래밍 콘테스트 챌린징 1 차례로 6, 2, 2, 2가 적힌 제비를 확인할 경우, 합이 12가 된다. 이런 경우, 유저가 승리한다.
  • 16. 문제 해결해보기 [문제] 당신은 유저가 선택한 제비의 목록과 K가 주어졌을 때, 유저가 승리할 수 있는지 판단하는 함수를 만들기로 했습니다. 아래의 지시사항을 확인하여 함수를 구현해보세요. * 문제 출처 : 프로그래밍 콘테스트 챌린징 1 [함수 정의] // input : 뽑은 제비가 담긴 배열 numbers, 만들고자 하는 값 k // return : 승리할 수 있는지 여부 T/F boolean canWin(int[] numbers, int k); [제한 사항] - 𝑁 ≤ 10 - 𝐾 ≤ 40
  • 17. 문제 해결해보기 가장 간단하게 아래와 같은 방법을 떠올려 볼 수 있습니다. numbers[0] + numbers[0] + numbers[0] + numbers[0] 는 K인가? numbers[0] + numbers[0] + numbers[0] + numbers[1] 는 K인가? numbers[0] + numbers[0] + numbers[0] + numbers[2] 는 K인가? numbers[0] + numbers[0] + numbers[0] + numbers[n-1] 는 K인가? numbers[0] + numbers[0] + numbers[1] + numbers[0] 는 K인가? numbers[n-1] + numbers[n-1] + numbers[n-1] + numbers[n-1] 는 K인가? … … 모든 경우의 수를 확인해보고 하나라도 참이라면? 유저가 승리
  • 18. 문제 해결해보기 아래와 같이 구현할 수 있습니다. 이 방법은 효율적인 방법인지 고민해봅시다. 각 4중 for문에서 for문이 n번 순회하므로 약 𝑛4 번에 비례한 연산이 일어난다. => 시간 복잡도는 O(𝑛4 )이다.
  • 19. 문제 해결해보기 조금만 생각해보면, 모든 경우를 확인해 볼 필요는 없다는 점을 알 수 있습니다. 1. 제비가 더해진 순서가 중요할까? - 예 : K=12일 때 {6, 2, 2, 2}, {2, 6, 2, 2}, {2, 2, 6, 2}, {2, 2, 2, 6}를 모두 확인할 필요는 없다. 𝑛𝑢𝑚 𝑎 + 𝑛𝑢𝑚 𝑏 + 𝑛𝑢𝑚 𝑐 + 𝑛𝑢𝑚 𝑑에 대해 𝑎 ≥ 𝑏 ≥ 𝑐 ≥ 𝑑인 경우만 검사해도 충분하다. 2. 1개 혹은 2개 혹은 3개의 숫자를 더했더니 K이상이 되었다면, 더 검사를 해볼 필요가 있을까? numa ≥ K 이거나 num 𝑎 + numb ≥ K 이거나 num 𝑎 + numb + numc ≥ K 인 경우, 네 숫자의 합이 K가 될 확률은 존재하지 않는다. - 예 : 현재까지 {6, 6}을 뽑았다. K=12라면 더 뽑아볼 필요가 없다.
  • 20. 문제 해결해보기 1 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 22 1 2 1 2 1 1 2 21 2 N=1, K=4이고 제비에 적힌 숫자가 {1, 2}인 경우 등장할 수 있는 경우의수를 모두 그려봅시다. 빨간색으로 칠해진 영역은 검사해보지 않아도 모든 경우의 수를 확인해 볼 수 있습니다 초록색으로 칠해진 영역은 합이 4가 될 경우가 없으므로, 확인해 볼 필요가 없습니다. 첫 번째 세 번째 두 번째 첫 번째
  • 21. 문제 해결해보기 4중 for문으로 시간 복잡도는 전과 같지만, 실제로는 𝑛4 보다 훨씬 적게 검사를 한다. 앞에서 정리한 내용을 구현하면 아래와 같다. 이처럼, 불필요한 계산과정을 건너뛰어 성능을 향상시키는 기법을 가지치기 라고 한다.
  • 22. 문제 해결해보기 [문제] 당신은 새로운 기능을 테스트하던 도중, 컴퓨터가 임의로 선택한 N개의 제비에 대해서 승리할 수 있는지 여부를 검사하는 과정에서 때때로 너무 많은 시간이 소요됨을 발견했습니다. 아래의 제약 사항에 맞추어 canWin() 함수를 수정해보세요 [제한 사항] - 𝑁 ≤ 100 - 𝐾 ≤ 400 [함수 정의] // input : 뽑은 제비가 담긴 배열 numbers, 만들고자 하는 값 k // return : 승리할 수 있는지 여부 T/F boolean canWin(int[] numbers, int k);
  • 23. 문제 해결해보기 우리는 3가지 숫자가 정해지면, 마지막 네 번째 숫자를 충분히 추정할 수 있습니다. 𝑛𝑢𝑚 𝑎 + 𝑛𝑢𝑚 𝑏 + 𝑛𝑢𝑚 𝑐 + 𝑛𝑢𝑚 𝑑 = K 라면 𝑛𝑢𝑚 𝑑 = K – (𝑛𝑢𝑚 𝑎 + 𝑛𝑢𝑚 𝑏 + 𝑛𝑢𝑚 𝑐)이기 때문 즉, 세 숫자를 정하고 𝑛𝑢𝑚 𝑑가 numbers[] 배열 내에 존재하는지 확인하면 된다. 실제로 성능이 개선되었을까요?
  • 24. 문제 해결해보기 3중 반복문의 시간복잡도는 𝑂 𝑛3 , 하지만 매 번 𝑛𝑢𝑚 𝑑를 찾기 위해서 𝑂(𝑛)의 탐색을 하므로 … 실제로는 𝑂 𝑛3 × 𝑛 = 𝑂(𝑛4 )으로 시간복잡도가 똑같다. 빠른 탐색이 필요하다? Binary Search? 하지만 Binary Search를 사용하기 위해서는 배열이 정렬이 되어있어야 한다… 배열을 정렬하는 데에는 또 그만큼 시간이 소모된다. 보통 대부분의 언어들에서는 Binary Search가 구현되어있다! 시간복잡도는 𝑂(log2 𝑛) 생각해보면 numbers[] 배열을 처음에 딱 1번만 정렬해두면, 계속 Binary Search를 사용할 수 있다. - numbers배열을 정렬 - 𝑂(n ∙ log2 𝑛) - 3중 for문을 돌며 binary search로 𝑛𝑢𝑚 𝑑를 numbers 배열 내에서 찾는다. - 𝑂(𝑛3 ∙ log2 𝑛)그러므로, 전체 시간복잡도는 𝑂 n ∙ log2 𝑛 + 𝑛3 ∙ log2 𝑛 = 𝑂 𝑛3 ∙ log2 𝑛
  • 25. 문제 해결해보기 아래와 같이 구현할 수 있다. - 내가 어떤 알고리즘을 사용할 수 있을지 생각해낼 수 있어야 한다. - 각 알고리즘의 조건, 특징, 원리에 대한 이해를 하고 정확히 사용해야 한다.
  • 26. 문제 해결해보기 [문제] 당신은 선택하는 제비의 개수가 많아졌을 때의 수학적 확률에 대한 연구를 하기로 했습니다. 기존의 canWin() 함수를 사용하던 도중, N이 1,000정도로 커지게 되면 또 다시 상당한 시간이 소요됨을 알게 되었습니다. 아래의 제한사항을 참고하여 canWin() 함수를 조금 더 개선해봅시다. [제한 사항] - 𝑁 ≤ 1000 - 𝐾 ≤ 4000 [함수 정의] // input : 뽑은 제비가 담긴 배열 numbers, 만들고자 하는 값 k // return : 승리할 수 있는지 여부 T/F boolean canWin(int[] numbers, int k);
  • 27. 문제 해결해보기 기존의 식 𝑛𝑢𝑚 𝑎 + 𝑛𝑢𝑚 𝑏 + 𝑛𝑢𝑚 𝑐 + 𝑛𝑢𝑚 𝑑 = 𝑘 에서 𝑛𝑢𝑚 𝑎 + 𝑛𝑢𝑚 𝑏 = 𝑋, 𝑛𝑢𝑚 𝑐 + 𝑛𝑢𝑚 𝑑 = 𝑌 로 두자. X + 𝑌 = 𝑘이므로 마찬가지로 Y = 𝑘 − 𝑋와 같은 식을 유도할 수 있다. 즉 배열 numbers[]에서 두 수를 정해 그 합 X를 정하면 Y의 값을 계산할 수 있다. 이 때 두 수의 합이 Y가 되는 경우가 존재하는지 검사할 수 있다면 문제를 빠르게 해결할 수 있다. 가능한 X의 경우의 수를 모두 탐색 : O(𝑛2 ) 계산된 Y를 만들 수 있는지 확인 : O(𝑛2 ) 이 때 X, Y ∈ 𝑛𝑢𝑚𝑖 + 𝑛𝑢𝑚𝑗 0 ≤ 𝑖 ≤ 𝑗 ≤ 𝑛 − 1} 임을 알 수 있다. numbers[] 배열의 두 원소의 합이 될 수 있는 모든 경우의 수를 미리 저장해둔다면?
  • 28. 문제 해결해보기 배열 twosum[] = 𝑛𝑢𝑚𝑖 + 𝑛𝑢𝑚𝑗 0 ≤ 𝑖 ≤ 𝑗 ≤ 𝑛 − 1} 이 있다고 가정해보자. 배열의 모든 원소를 하나씩 탐색한다. - 모든 X의 경우의수를 판단할 수 있다. twosum[] 배열이 정렬되어 있다면? - twosum[] 배열 안에 Y가 존재하는지 Binary Search로 확인하면 된다. 1. twosum[] 배열을 생성한다 – O(𝑛2 ) 2. twosum[] 배열을 정렬한다 - O(𝑛2 ∙ log2 𝑛) 3. twosum[] 배열을 순회하며 X를 정한다. – O(𝑛2 ) - X를 통해 계산한 Y가 twosum[] 배열 안에 존재하는지 확인한다 – O(log2 𝑛) 시간복잡도는 O n2 + n2 ∙ log2 𝑛 + 𝑛2 ∙ log2 𝑛 = 𝑂(𝑛2 ∙ log2 𝑛)
  • 29. 문제 해결해보기 이를 직접 구현한 코드는 아래와 같다.
  • 30. 문제 해결해보기 [Key] 자주 계산해야 하는 값을 매번 계속하지 않고 어딘가에 저장해둔 후 바로 가져와 사용하면 시간을 절약할 수 있다. 단, 많은 메모리를 사용해야 한다는 단점이 있다. 이런 방법을 Memoization이라고 한다. 각 알고리즘의 시간복잡도 별로 근사 연산량을 비교해보자 𝒏 𝑂(𝑛2 ∙ log2 𝑛) 𝑂(𝑛 𝟑 ∙ log2 𝑛) 𝑂(𝑛 𝟒 ) 10 300 3,000 10,000 100 60,000 6,000,000 100,000,000 1,000 9,000,000 9,000,000,000 1,000,000,000,000 알고리즘의 시간복잡도의 차이는 n의 크기가 클 수록 큰 성능 차이를 만들어낸다.
  • 31. 문제 해결해보기 당신은 요즘 유행하는 2D FPS 게임 ‘썩은어택’의 개발자입니다. 이 게임은 유저가 버튼을 누를 때 마다 임의의 N개 점에 총알들이 날아가게 됩니다. 2차원 평면상에 NPC가 그려진 영역 안에 총알이 위치할 경우 Hit Count가 1이 증가하게 됩니다. 각 NPC는 움직이지 않고 정지해 있으며, 각 NPC를 그리는 점들은 배열로 주어집니다. 당신은 유저가 총알들을 발사할 경우, 총알들과 NPC들간 충돌 체크에서 상당한 렉이 발생함을 알게 되었습니다. 한 NPC와 한 총알의 충돌을 체크하는 함수가 주어집니다. 이 함수를 사용하여 총 N개의 총알과 총 M개의 NPC에 대해 Hit Count를 최대한 빠르게 구하는 방법을 설계해보시오. 한 NPC는 보통 𝑝𝑖개의 점으로 이루어 져 있으며, 서로 영역이 겹치는 NPC는 없다. 맞은 총알 빗겨간 총알
  • 32. 문제 해결해보기 기존의 소스코드는 아래와 같이 작성되어 있다고 가정합시다. 위 알고리즘의 시간복잡도는 몇일까요? 한 NPC를 그리는 점의 개수를 𝑝𝑖라 할 때의 시간복잡도 𝑂(𝑛 ∙ 𝑚 ∙ 𝑝𝑖)
  • 33. 문제 해결해보기 아래의 예시를 봅시다. 총알 A에 비하여 총알 B는 눈으로 보기에 굳이 충돌 검사를 할 필요가 없어 보입니다. 이렇게 멀리 떨어져있는 점과 NPC는 충돌검사를 하지 않는다면 시간을 절약할 수 있을 것 같습니다. 즉 가지치기가 가능해 보입니다. B A 어떻게 하면 총알 B 같은 경우를 빠르게 가지치기 할 수 있을까요?
  • 34. 문제 해결해보기 NPC를 완전히 포함하는 최소의 직사각형이 있다고 가정해봅시다. B A 저 직사각형 밖의 점에 대해 충돌검사를 할 필요가 있을까요? 한 점이 NPC의 영역에 포함되는지 검사하는 데에 필요한 시간복잡도 : O(𝑝𝑖) 한 점이 직사각형에 포함되는지 검사하는 데에 필요한 시간복잡도 : O(1) 즉, 답이 될 가능성이 없는 점(사각형 밖의 점)에 대해선 빠르게 검사가 가능합니다.
  • 35. 문제 해결해보기 한 NPC을 포함하는 직사각형을 찾는 방법 : O(𝑝𝑖) 하지만, 한 NPC에 대해 직사각형을 한번 구해둔 후 저장해두면 모든 점과의 충돌 검사에 사용할 수 있다. 즉, 직사각형의 좌표를 Memoization을 해둘 수 있다.
  • 36. 문제 해결해보기 또한 … 두 NPC는 서로 영역을 공유하지 않습니다. 즉, 한 총알은 두 개 이상의 NPC와 충돌할 리 없습니다. 이미 어딘가에 충돌한 적이 있는 총알이라면 충돌검사를 할 필요 없습니다. 해당 총알이 NPC에 충돌한 적이 있는지 여부를 Memoization한다면? 이 처럼 같은 기능을 구현하더라도, 다양한 방법으로 최적화 할 수 있는 방법이 존재합니다. 이렇게 많은 방법들 중 현재 가장 적합한 방법을 찾아낼 수 있어야 합니다
  • 37. 문제해결능력 기르기 하나 많이 고민하고, 많이 코딩 해보기 어떻게 구현할까? 다른 방법은 없을까?내 방법이 정확한가? 코드를 더 간결하게 작성할 수 있을까? 코딩을 하기 전 다양한 방법을 머릿속으로 생각해보기 코딩을 하면서도 더 좋은 방법이 없는지 계속 고민하기 경험적으로 쌓이는 코딩센스도 중요합니다!
  • 38. 문제해결능력 기르기 둘 정확히 이해하고 ‘잘’ 활용하기 수학, 알고리즘, 라이브러리, 프레임워크, 검색 까지… 나를 도와줄 수 있는 모든 것들 무엇을, 언제, 어떻게 활용할지를 결정하는 것도 문제해결능력 ‘얼마나 많이 아는가’ 보다 중요한 것은 ‘얼마나 잘 활용할 수 있는가’ 알고리즘 라이브러리 지식창고 단순히 ‘안다’, ‘사용해봤다’에 만족하지 말고 정확히 이해하고 활용해봅시다.
  • 39. 문제해결능력 기르기 셋 다른 사람의 아이디어 배우기 사람마다 지식도, 경험도, 아이디어도 모두 다를 수 밖에 없다. 같은 것을 구현한 다른 사람의 코드를 보고 자신의 방법과 비교해보자. 모르는 것은 지나치지 말고 물어서라도 알고 넘어가기 다른 사람의 아이디어를 배울 수 있는 방법은 수 없이 많다.
  • 40. 문제해결능력 기르기 하나 많이 고민하고, 많이 코딩 해보기 둘 정확히 이해하고 ‘잘’ 활용하기 셋 다른 사람의 아이디어 배우기 요약해보면 … 너무나 당연한 내용이지만 실천하기는 쉽지가 않다!
  • 41. 문제해결능력 기르기 추천하는 방법 프로그래밍문제 풀어보기 원하는 언어로 다양한 프로그래밍 연습을 할 수 있다. 다양한 상황, 제한사항에 따라 다양한 방법을 고민해볼 수 있다. 다른 사람의 코드를 보거나 검색해보면서 다양한 스킬을 익힐 수 있다. 지적유희? 다양한 문제를 풀어보면 어떤 점이 좋을까? 다양한 문제를 프로그래밍으로 해결하고 소스코드를 제출하는 방식 다양한 상황, 제약사항을 가정하고 가장 적합한 방법을 찾아내야 한다. 설계된 방법을 정확히 구현해야 한다.
  • 42. 문제해결능력 기르기 프로그래밍 문제를 풀어볼 수 있는 다양한 사이트들 Lavida.us 친구와 코딩 배틀을 할 수도 있고 실제로 다양한 대회도 열리고 있다
  • 43. 세 줄 요약 문제해결능력이란 문제를 정확히 이해하고 가장 적합한 방법을 찾고 구현하는 능력 어떤 개발을 하게 되더라도 프로그래밍의 질적 차이를 만든다. 다양한 프로그래밍 경험과 문제해결능력이 시너지를 이루는 좋은 개발자가 됩니다. 
  • 45. URLs Lavida Online Judge - http://lavida.us Baekjoon Online Judge - http://acmicpc.net Dovelet - http://dovelet.com Algospot Online Judge - http://algospot.com Codeforces - http://codeforces.com TopCoder - http://topcoder.com/tc Google Code Jam - http://code.google.com/codejam

Notes de l'éditeur

  1. 저는 첫 순서로 강연을 하게 된 김동이라고 합니다. 간단히 제 소개를 드리면 현재 아주대학교에서 컴퓨터 공학을 전공하고 있는 평범한 대학생 12년도에 입학한 이후부터 쭉 ANSI에서 활동 프로그래밍과 알고리즘 자체는 중학교 때부터 공부를 했습니다. 다른 이유 보다는 재미있기도 하고 알아두면 도움이 될 것 같다는 생각에 공부를 해왔고, 정보 올림피아드에 나가서 만년 지역 2등으로 놀다가 대학교에 들어와서 대회에 흥미를 가지기 시작해서 본격적으로 공부를 하기 시작했습니다. 12/13년도에는 ACM ICPC에 출전하며 알고리즘을 공부했었구요 다른 분들도 많이 느끼는 생각이지만, 개발을 좀 해보고 싶다- 란 생각에 다짜고짜 휴학을 결정하고 약 2년 정도 회사를 다니다가 올해는 복학을 한 후 다시 대회를 준비하고 있는 상태입니다.
  2. 오늘 제가 강연을 할 내용을 ‘문제해결능력’이라는 하나의 키워드로 요약을 할 수 있습니다. 조금 생소하실 수 도 있고, 어딘가에서 들어본 적도 있으실 텐데 먼저 문제해결능력이 그럼 무엇이고 왜 중요한지 그리고 알고리즘과는 어떤 관련이 있는 건지에 대한 이야기를 할 꺼구요 그 다음에는 이런 문제해결능력에 대한 감을 잡고, 실제로 어떻게 적용할 수 있을지 알아보기 위해서 실제로 다양한 프로그래밍 문제를 함께 고민해보는 시간을 가질까 합니다. 그리고 앞에서 이야기한 내용을 바탕으로 중요하구나-라는 생각이 드셨다면, 어떻게 공부해야할 지 궁금하실텐데 공부를 하는 방법에 대한 이야기를 잠시 할까 합니다.
  3. 먼저 설명에 앞서서 제가 이야기드릴 내용은 기본적으로 이번 컨퍼런스와 동일하게 프로그래밍을 공부했고, 알고리즘과 자료구조를 수강했거나 혹은 공부하고 있는 분들을 대상으로 하고 있구요 혹시 프로그래밍 공부를 하면서 이런 의문 혹은 걱정을 가져본 적이 있다면 제가 말씀 드릴 내용이 조금이나마 도움이 될 수 있다고 생각합니다
  4. 먼저 문제해결능력이라는 단어에 대해서 설명을 드리자면 가장 먼저 그냥 ‘문제’라고만 하면 시험지에 있는 문제가 떠오른다거나 상당히 다양한 의미가 떠오를 수 있는데요 제가 이번에 말씀드리는 내용에서 이 ‘문제’라는 단어는 보시는 것 처럼 우리가 프로그래밍을 하면서 맞닥드리는 상황 즉, 무엇인가를 개발해야 하는 상황을 이야기 하구요 ‘해결’이라는 것은 간단히 말해서 구현을 하는 건데, 단순히 구현을 막 해서 끝내는 것이 아니라 정확히 문제를 분석해서 다양한 방법을 고려해보고, 지금 상황에 가장 적합한 방법을 찾고, 또 그것을 정확히 구현하는 것을 말합니다 그래서 제가 말하는 문제해결능력이라는 것은 단순히 문제를 풀거나, 그냥 구현을 하는 것이 아니라 문제를 분석하는 능력, 프로그래밍 지식, 판단력, 어떤 방법을 슬 것인가에 대한 아이디어, 사고력, 또 응용할 수 있는 알고리즘 지식까지 다양한 능력을 아우르는 단어입니다. 아무래도 이게 무슨 소리인가, 될놈만 된다는 소리인가 하는 생각을 하실 수도 있는데 그런 내용은 아니구요 자세히 들어가보면
  5. 앞에 말씀 드린 단어들의 정의대로 문제를 해결하는 과정을 요약해보면 먼저 해결해야 할 상황에 대한 분석 즉, 내가 어떤 것을 만들어야 하고, 고려해야 될 제한사항은 무엇인지에 대한 분석이 우선되어야 하구요 분석이 끝난 후에는 그러면 이러한 조건들을 만족하는 가장 좋은 방법은 무엇인지, 또 어떻게 해야 효율적으로 개발할 수 있을지에 대한 전략을 세우는 과정을 설계라고 할 수 있습니다. 그 후에 내가 설계한 대로 정확히 구현하는 것으로 문제 해결과정이 끝난다고 할 수 있는데요 그림으로 다시 살펴보면, 우리가 어떤 나무집을 만든다고 상황을 가정했을 때, 제작에 사용되는 재료를 프로그래밍 언어라고 할 수 있을 것이구요, 어떤 집을 만들어야 하는지에 대해 분석을 거친 후에 어떤 모양의 집을 어떤 방식으로 만들 것인지에 대한 설계가 이루어지고 이제 설계된 사항을 최대한 반복작업없이 효율적으로 제작할 수 있는 전략을 세워 구현을 하면 그 결과로 생성된 나무집이 우리가 작성한 코드 혹은 프로그램이라고 할 수 있습니다.
  6. 그러면 도대체 이 문제해결능력이라는 것이 이번 컨퍼런스의 주제인 알고리즘과 어떤 관련이 있는 건가에 대한 의문을 가지실 수 있는데요 먼저 다들 아시겠지만 잠시 뜻을 살펴보면 알고리즘이란 – 자료구조란 – 즉 알고리즘이고 자료구조건 학자들이 뜬금없이 아 이러면 좋겟다-해서 만든 것이 아니라 실제로 어떤 문제를 해결하기 위해서 그에 대한 방법을 고민하고 필요한 사항들을 설계하면서 만들어진 결과물이라고 할 수 있습니다. 즉, 우리가 수업에서 배우는 알고리즘이라는 것은 하나의 문제해결전략을 정형화하고 일반화한 형태라고 할 수 있습니다 우리가 꼭 이런 알고리즘을 직접 활용하는 솔루션을 개발하고 신기술을 개발할 때에만 사용하는 것이 아니라 이 알고리즘을 응용해서 실제 개발할 때에 활용할 수 있고, 작게는 그 알고리즘에서 사용된 작은 아이디어들을 응용할 수 도 있고 또 그만큼 많이 알수록 한 문제에 대해 다양한 방법을 생각해볼 수 있는 폭을 넓힐 수 있게 됩니다 즉 제가 하고싶은 말은 알고리즘을 공부하는 건 단순히 지식을 늘리는 것 뿐만 아니라 문제해결능력을 기르는 가장 효과적인 방법 중 하나라는 것이구요
  7. 만약 하나의 상황을 가정해보고, 우리가 개발을 하려고 고민을 하던 도중에 세 가지 방법이 떠올라서 화면에 보이는 것 처럼 표를 그려서 각 알고리즘을 비교한다고 생각해봅시다. 만약 입력의 크기가 작아서 속도는 크게 영향이 없지만, 메모리를 많이 사용할 수 없는 상황이다 – 하면 A라는 방법을 사용 할 수 있겠고 만약 큰 서버에서 실시간 서비스를 제공해야 한다-라고 하면 조금 메모리의 소비를 감수하면서라도 B 같은 방법을 사용할 수 있겠죠 C같은 방법은 빠르고 메모리고 적게 사용하지만, 원하는 결과를 알 수 없는 엉터리 알고리즘이라고 할 수 있죠 그러면 이제 우리가 다양한 알고리즘을 알았을 때 생각해볼 수 있는 상황을 고려해봅시다 조금 생각을 정리해봤더니 방법 A ‘갑 알고리즘’을 적용할 수 있었단 사실을 알게되어 적용해보았더니 A2 방법처럼 성능이 꾀 개선되는 경우가 있을 수 있구요 아까 메모리를 꾀 사용했지만 괜찮은 성능을 내던 방법 B에 어떤 자료구조를 적용했더니 (해쉬테이블) 메모리를 더 많이 사용해요, 그런데 정말 범접할 수 없는 성능을 낸다 (크롬) 정말 이렇게 속도가 중요한 상황에선 이런 방법을 사용을 해야겠죠 그리고 마지막으로 방법 C에 어떤 확률적인 수학 알고리즘을 적용해보았더니 속도나 메모리 효율이 상당히 좋고 결과값도 어느 정도 근사하게 얻을 수 있다고 해봅시다 만약에 뭐 어떤 거리나 온도처럼 아날로그 데이터는 실제로 정확한 답을 구하기도 힘들 고 그렇게 정밀한 데이터가 필요한 경우가 드물죠 그런 경우가 아니라면 과감하게 C2라는 방법을 선택하는 것이 가장 좋은 방법이라고 할 수 있겠죠 이처럼 다양한 알고리즘이나 자료구조를 알고 이해하고 있으면, 이를 이용해 실제 개발을 할 때에 다양한 방법에 대한 설계가 가능해지고 또 그런 많은 방법 중 방금 했던 고민처럼 어떤 방법이 가장 좋은건지에 대해서 분석하고 선택하는 능력이 앞에서 말씀 드린 문제해결능력이 됩니다 그러면 알고리즘과 문제해결능력이 어떤 관계에 노여있는지 이해가 가셨을 꺼라고 생각하고
  8. 그러면 이런 문제해결능력이 얼마나 중요한데, 개발 공부하기도 바쁜데 이런 능력을 강조를할까 하는 의문을 가지는 분들도 계실 수 있는데요 우리가 재료와 도구들을 구해서 어떤 물건을 만드는 과정을 한번 상상해볼께요 당연히 물건을 만들기 위해서는 원재료가 있어야 하겠죠 그리고 또 제작을 도와줄 연장들 혹은 이미 어느정도 만들어져 있는 블록들이 있을 수 있겠죠 요즘 DIY제품도 많이 나오니까요 그리고 우리가 직접 만드는 과정에서 눈에 보이진 않을수도 있지만 결국 우리가 무언가를 만들어본 경험, 그리고 도구를 사용하는데에도 재료나 도구에 대한 이해나 다루는 숙련도, 그리고 만드는 물건에 대한 정확하고 효율적인 설계가 작용이 되고 그런 과정을 거쳐서 물건을 제작 할 수 있겠죠 그렇다면 만약에 똑같은 재료나 도구가 우리에게 주어졌고 똑같은 물건을 만든다고 했을 때 모든 사람이 물건을 만드는 속도, 물건의 품질, 물건의 디자인이 같을 순 없겠죠 왜냐하면 앞에서 말한 개인이 가지고 있는 저런 스킬들이 알게모르게 제작 과정에 관여가 되고 결과물의 차이를 만들어 내겠죠 이걸 이제 프로그래밍에 투영해서 살펴보면 이렇게 볼 수가 있죠
  9. 앞에서 똑같은 도구 혹은 재료를 가정하고 또 개인 역량에 대해 이야기를 했던 이유는 먼저, 다들 아시다시피 정말 많은 곳에서 코딩을 공부한다, 코딩열풍이다 라는 말이 불고있죠 앞에 기사들도 거르고 걸렀는데도 정말 다양한 기사들이 있었는데요 중고등학교 의무교육부터 시작해서, 타른 전공자들의 복수전공이나 취업준비용 코딩교육 코딩배워 재취업 하기등 그만큼 코딩에 대해 증미나 필요를 느낀 사람이 많고, 또 접하기 쉽다는 이야기죠 뭐 사실 어떻게보면 그렇게 만만하게 보이는 걸까 하는 생각도 들기도 하는데 말했던 것 처럼 이렇게 배우는 사람이 많아지는 이유 중 하나는 우리도 느끼듯이 갈수록 진입장벽은 낮아지죠 정말 다양하고 좋은 라이브러리가 오픈소스로 공개되고, 프로그래밍 강의도 무료에 다양한 개발도구도 대학생 대상으론 무료라던가, 또 좋은 책, 쉽게 정보를 얻을 수 있는 사이트까지 컴퓨터만 있고 마음만 먹으면 코딩을 할 수 있게 되었죠 또 이런 와중에 우리는 배울 것은 계속 늘어나죠 하나의 서비스를 개발한다고 하나의 언어나 플랫폼만 쓰는 게 아니고, 기능별로 분류해서 서비스를 만들고 플랫폼별로 또 만드는데, 언어마다 새로운 라이브러리 프레임워크가 나오고 용도마다 장단점도있고 심지어 그걸 개발하는 툴조차 너무나도 많이나오죠 그래서 앞에 가정했던 것 처럼 정말 많은 사람들이 누구나 쉽게 새로운 언어나 개발에 도움되는 지식들을 접할 수 있게 되었고
  10. 결국 개발자들간에 차이가 될 수 있는 것은 같은 개발을 하더라도 더 수준 높고 더 완벽한 개발을 할 수 있는 폭넓고 심도 있는 개발경험 그리고 무엇으로 무엇을 개발하더라도 기본적으로 프로그래밍이라는 본질 하에서 작용하는 개인의 문제해결능력 이 두 가지라고 할 수가 있죠 물론 더 있을 수도 있지만 그래서 이걸 게임과 비교해보면 우리 개발자 자체는 하나의 캐릭터라고 할 수가 있고 위에서말한 이런 역량들은 하나하나가 캐릭터의 레벨, 능력치라고 할 수 있죠 그리고 개발 기술들은 하나의 아이템으로 볼 수 있겠죠 그리고 그런 기술들에 대한 심도 즉 숙련도가 아이템의 숙련도 라고 할 수가 있겠죠 적재적소에 쓸 수 있는 다양한 아이템도 중요하지만, 그걸 다루는 캐릭터의 능력치, 그리고 숙련도가 중요하다고 할 수 있는데요 저는 저 두가지 중 오늘 이야기하고자 하는건 개발자의 능력치를 올리자-라는 주제로 볼 수 있습니다.
  11. 실제로 저 혼자서 이런 생각을 하고 결론을 내리는 것이 아니라 주변에 계신 제 개발자 지인분들의 의견들이나 다양한 인터뷰 혹은 보시는 것 처럼 신문 기사들에서도 알 수 있듯이 기업들도 이러한 상황을 인식하고 있고, 결국 이런 문제해결능력이 중요하다는 걸 알고 있습니다. 특히 아직 숙련도가 낮은 신입 개발자라면 더 기대해 볼 수있는건 캐릭터의 능력치다-라고 할 수 있겠죠
  12. 그러면 실제로 개발을 하면서 거치는 이런 문제 해결 과정에 대해서 이야기를 해볼 건데요 다른 것도 많겠지만 주로 우리가 여러 방법 즉 알고리즘을 떠올리고 설계할 때에는 이런 사항들을 고려하게 되는데요 얼마나 빠른 알고리즘인지 메모리는 얼마나 사용하는지 그러면 항상 정확한 답을 내는지, 아니면 얼마나 근사한 답을 구할 수 있는지 그리고 이 알고리즘을 실제 구현하는데 얼마만큼의 시간이 걸리고 얼마나 복잡한지 더 좋은 방법은 없는지 이런 고민을 통해서 좋은 방법을 선택하는게 중요하다고 할 수 있습니다.
  13. 그러면 이제 실제로 어떤 개발을 하는 상황을 가정해보고, 문제해결을 경험해볼껀데요 일단 문제 자체는 두개밖에 되지 않지만, 한 문제도 여러 방법으로 해결이 가능하단 걸 보여드리고 그리고 개발할때 특히 자주 사용될 수 있는 몇가지 코딩 센스라고 할까요 기법을 알려드릴까 합니다. 문제를 읽고 자신의 대답을 고민해보면서 어떤 알고리즘이나 해답을 알아서 외워가겠다-보다는 저런 식으로 아이디어를 낼 수 있구나 하는 거에 초점을 맞춰주시면 좀 더 좋을 것 같습니다. 그래서 일부로 어떤 특정한 유명한 알고리즘이 사용되기 보다는 코딩스킬을 활용할 수 있는 문제로 준비를 했으니까 한번 보겠습니다.
  14. 앞에서 받은 문제지에 적힌 문제중에 첫 번째 문제인데요 그래도 간단히 다시 요약을 해보면 제비뽑기라는 게임을 개발하던 와중에, 유저가 승리할 수 있는지 여부를 체크하는 함수를 작성을 할 겁니다. 게임 규칙은 앞에 보시는 것 처럼 유저가 자연수가 적힌 임의의 N개의 제비를 선택하게 되고, 저희가 만들 함수에 파라미터로 주어지게 됩니다. 그래서 이 제비들이 만약 모두 뒤로 뒤집혀있다고 가정을 하고, 한 카드를 뽑아 번호를 확인하고, 다시 뒤집은 후 모두 섞고 이런 과정을 4번 걸쳐서 확인된 네 숫자의 합이 K가 될 수 있는가-를 판단하는 함수를 만드는게 이 문제의 목적이 되는데요 앞에 예제를 보시면
  15. 자 아래 지시사항대로 함수를 만들게 될 것인데, 먼저 제한사항을 봅니다. 입력되는 값이 충분히 작으니까 다양한 방법을 떠올릴 수 있는데요
  16. 먼저 배열에 값들이 들어있다고 생각을 해보면 총 N개의 값중에 중복을 포함해서 4개를 선택하면 되므로 총 N^2가지의 경우에수가 앞에 나열한 것 처럼 존재하고, 각 경우의 수에 대해서 그 네 숫자의 합이 K가 되는지를 if문으로 검사를 하고, 하나라도 참이라면, true를 리턴해주면 되고, 그렇지 않고 모든 경우에수에서 K가 되는 값이 없었다면 false를 리턴해주면 되겠죠
  17. 이 방법을 구현해보면 아래처럼 a,b,c,d라는 네 변수로 4중 반복문을 돌면서 각각 0~ n-1까지 반복문을 순회해서 각 배열의 a, b, c, d번째 값을 더하고 K와 비교하는 과정을 거칩니다. 그럼 이 방법의 시간복잡도를 구현해보면 N^4이 되고 N이 10정도라고 가정하면, 많아봐야 10,000번 정도의 비교를 하면 충분히 짧은 시간내에 함수가 종료될 수 있겠죠
  18. 그런데 이런 간단한 방법에 대해서 이야기 하고자 이런 문제를 드린 것은 아니구요 우리가 이런 단순한 알고리즘도 조금만 생각을 해보면, 성능을 엄청나게 개선시킬 수 있다는 사실을 알 수 있습니다. 어떤 새로운 방법을 떠올리는 게 아니라 우리가 모든 경우의수를 탐색을 하지만, 실제로 생각을 해보면 먼저 제비를 네 번 뒤집지만 결과적으로 우리가 알아낸 네 숫자의 순서는 중요하지 않다는 사실을 알 수 있습니다. 그러니까 모든 순열의 경우의수를 우리는 탐색하고있지만, 더한 결과값만이 중요하므로 모든 조합의 수만 검사를 하면 된다는 사실을 알 수 있습니다. 이렇게만해도 정말 많은 탐색횟수를 줄일수가 있고 또 숫자를 차례로 더하다 보면 숫자 네개를 아직 다 더하지 않았는데도 이미 K라는 값 이상이 되어버리는 경우가 발생할 수 있습니다. 문제를 잘 읽으셧다면 모든 제비에 적힌 숫자는 자연수라는 점을 알 수 있고, 그 특징을 사용하면 도중에 K이상이 되어버리면 더이상 하위 반복문은 탐색을 하지않고 건너 뛸 수 있다는 사실을 알게됩니다.
  19. 앞에서 말한 두 가지 사항중에 먼저 첫 번째 사항처럼 모든 조합에 대한 검사를 한다고 하면, 그림에서 보이는 빨간색 영역을 검사하지 않더라도 모든 조합에 대한 검사를 할 수 있게 되고 마찬가지로 더하는 도중에 K가 4 이상이 되는 경우 그 하위 경우를 검색하지 않는다고 하면 이런 초록색으로 칠해진 영역만큼 탐색횟수가 줄어들게 됩니다.
  20. 그럼 이 사항들을 적용해서 앞에 작성했던 코드를 수정해보면 어째 if문이 조금 맣아져 코드가 조잡해진 것 같지만, 만약 N과 K가 커져서 성능이 좀 더 중요해진다면 이 방법을 사용하는게 훨씬 효율적이라고 할 수 있습니다. 마찬가지로 4중 반복문을 돌기 때문에 시간 복잡도는 마찬가지로 O(n^4)이지만, 실제 연산량은 훨씬 적고 이렇게 문제를 분석해서 불필요한 계산이나 탐색 과정을 건너뛰어 실제 성능을 향상시키는 기법을 쉽게 가지치기 라고 하고 이 기법은 우리가 생각해보면 반복문을 사용하는 모든 경우에 사용이 될 수 있습니다.
  21. 그럼 조금 문제를 확장시켜 보겠습니다. N이 10정도일 때에는 10의 네 제곱번 연산을 해도 실제 연산량은 약 1만 정도여서 그렇게 많은 시간이 소요되지 않았지만 N이 100정도로 커지게 된다면, 약 약 1억번의 연산을 하게 되고, 1억번 정도면 엄-청 많이 시간이 걸리는 정도는 아니지만, 그래도 조금 버벅임을 인지할 정도는 되기때문에 새로운 방법을 고민할 필요가 있습니다. N과 K가 아래와 같이 좀 더 커졌을 때 새로운 방법을 찾아봅시다.
  22. 우리가 생각을 해보면 K를 알고 있기에, 숫자 네개가 아니라 세개만 정해지더라도, 마지막 숫자는 식을 정리해 계산을 할 수 있음을 알 수 있습니다. 즉, 세 숫자가 정해져있다면 네 번째 숫자를 알 수 있고 이 숫자가 numbers배열에 존재하는지 검사를 해서 존재한다면 식을 만족하는 값이 존재함을 알 수 있습니다. 그러면 3중 반복문으로 숫자 세 개를 정한 후에 네번째 숫자를 계산하고, for문을 통해 numbers에 네번째 값이 있는지 확인합니다. 그런데 이렇게 구현을 한다면 성능이 개선되었다고 할 수 있을까요? 결국 탐색에 n번 만큼 반복문을 돌기 때문에 시간복잡도는 아까와 같이 O(n^2)가 됩니다. 방법은 좋았지만 우리가 생각한 것 만큼 성능이 좋거나 하지는 않죠
  23. 이제 미련을 버리지 못하고 네 번째 숫자를 빠르게 찾을 수 있는 방법이 있지 않을까-하는 고민이 들 수가 있습니다. 기억을 되살려보면 아마 자료구조, 알고리즘, 프로그래밍 수업들에서 뭔가를 빠르게 탐색할 수 있는 알고리즘인 바이너리 서치가 있었다 란 생각이 들 수가 있는데요. 대부분의 언어들에서도 바이너리서치가 편리하게 구현이 되어있고, 속도도 상당히 빠른데 그럼 그냥 이거를 사용하자!란 생각을 하고 그냥 사용을 하게되면 안되구요 알고리즘에 대한 정확한 이해가 필요하다는 이유가 여기서 하나가 나오는데요 바이너리서치는 사용을 하기위해서는 사용하는 배열이항상 정렬되어있어야 한다는 조건이있습니다. 그렇다면 따로 이 numbers라는 배열을 정렬을 해야할까-하는 고민을 해보아야합니다. 분명 배열을 정렬하면 그만큼 시간이 소모될텐데 시간이 급한 이 상황에 사용할 수 있을까요
  24. 그러면 이제 이미 구현되어있는 기능을 사용해 이 알고리즘을 구현해보면 이렇게 코드를 작성할 수 있습니다. 그래서 아 이 문제는 이렇게 푼다- 가 아니라 알고리즘을 알고있으면 이렇게 중간중간 활용을 할 수 있고, 그냥 알면안되고 사용하기 위한 조건은 무엇인지, 얼마만큼 효율을 낼 수 있는지에 대한 충분한고민을 거쳐야 합니다.
  25. 앞에 설계했던 알고리즘은 n^3 log 2 n 정도로 N이 1000정도가 되었을때 대충 100억번의 연산이 필요하다는 사실을 알 수 있습니다. 그러면 또 어떻게 시간을 줄여야 연산량을 줄일 수 있을까요 자 새로운 방법을 한번 같이 고민을 해보도록 하겠습니다.