본문으로 바로가기

알고리즘 문제풀이(PS) 시작하기

category PS - OJ/BOJ 2016. 12. 23. 20:17

이런건 고수들이나 써야 하지 않나 싶지만,

그래도 1년정도 공부하면서 이 분야를 어떻게 시작해야 할지 써보려 한다.

 

▶ 어떻게 공부해야할까?

 

나는 아직도 PS(Problem Solving)를 잘 못하지만,

주변에 처음 시작하는 사람들이 내게 PS 공부 방법에 대한 고민을 자주 털어놔서 글로 정리해보려고 한다.

 

ps를 처음 시작하면 online judge에 들어가서 몇 문제를 풀어봤을 것이다.

근데, 문제를 풀어봐도 내 실력이 느는 느낌도 안나고,

문제 하나 푸는데 시간도 엄청 걸리고,

풀 수 있는 문제도 거의 없다.

 

이때 주변에 잘하는 사람이 있어서 도움을 받으면 최고로 좋은 케이스지만,

보통 나 같은 사람들은 도움 받을 사람도 없고

인터넷을 뒤적뒤적하고 책을 찾게 된다.

 

근데 또 책은 왜이렇게 진도가 안나가?

코드를 읽으면 자꾸 모르는 STL이 등장하고,

이거 찾아보고 익히는데 또 한참 걸리고,

나중에 돌아와서는 다시 코드 로직을 뜯어봐야하고

다시 내가 문제를 직접 풀어보는데 헤매고.. 그러다보면 하루종일 붙들고 있어도 3~4페이지도 못나간다.

 

그렇다고 문제부터 풀면서 시작하자니 어떤걸 풀어야 할지도 모르겠고,

이것저것 건드려는 보는데, 역시나 풀어봐야 실력이 전혀 오르는거 같지 않다.

 

▶ 어디서부터 문제일까?

어디부터 공부해야할까?

 어떤 문제를 풀어야 할까?

 도움은 어디서 받아야 할까?

 문제를 이렇게 오래잡고 있어도 될까?

 모르는 STL은 한방에 묶어서 누가 해결 좀 해줬으면 좋겠다...

 

이런 생각을 가진 분들이라면 이 글을 읽어볼만 하다.

 

 

내가 자주 하는 말이 있는데,

모르는 사람은 본인 스스로가 무엇을 모르는지 모른다.

자기 스스로가 모르고 있다는 사실 조차 모르는 것이다.

그렇기 때문에 뭘 물어봐야 하는지도 모른다.

그래서 모르는 부분이 무엇인지부터 알아야한다.

 

모르는 부분은 어떻게 알 수 있을까?

사실 제일 쉬운방법은 주변에 잘하는 사람에게 도움을 청하는 것이겠지만,

이 글을 읽고 있는 사람은 아마도 주변에 잘하는 사람이 없는 상태일 것이므로

다음과 같은 문제를 풀어보면서 내가 아는 부분은 넘기고 모르는 부분을 빠르게 채워나가는 것이 좋다.

처음부터 책과 씨름하지 말자. 알고리즘 시작도 못해보고 퍼지기 딱 좋다.

 

 

BOJ에서 다음 문제들을 쭉 순서대로 풀어본다.  boj.kr/문제번호 <= 형태로 검색하면 된다.

입출력 - 2557, 1000, 2558, 10950, 10951, 10952, 10953, 11021, 11022, 11718, 11719, 11720, 11721, 2741, 2742, 2739, 1924, 8393, 10818, 2438, 2439, 2440, 2441, 2442, 2445, 2522, 2446, 10991, 10992

 

입출력 문제들을 풀 때 10분이상 이 문제를 붙들고 있는 경우, 그건 입출력에서 뭔가 모르는 부분이 반드시 있다는 뜻이므로 이전 질문들을 무조건 찾아보고 다른 사람이 푼 코드를 반드시 봐야 한다. 이 때 코드 길이 줄이려고 이상하게 짧은 코드들 많은데, 그런건 보지 말고 랭킹 100위권 안에 드는 사람들 중 인덴트 멀쩡한 코드를 보면 된다.

 

그 다음 DP문제를 풀어보자.

 

DP - 1463, 11726, 11727, 9095, 10844, 11057, 2193, 9465, 2156, 11053, 11055, 11722, 11054, 1912, 2579, 1699, 2133, 9461, 2225, 2011, 11052

백준님은 모르는 문제가 있으면 2시간을 넘기지 말라고 했는데, 나는 이런 기초 문제는 1시간을 넘길 필요가 없다고 생각한다. 흔히들 PS를 처음 접하는 사람들이 하는 큰 실수가 모르는 문제를 하루종일 붙들고 있는 건데, 우린 수학이란 과목을 정규과정만으로는 초등학교 6년, 중학교 3년, 고등학교 3년 동안 배웠다. 그런데 알고리즘에는 그만한 시간을 투자할 수 없다. 그러나 알고리즘의 양은 그만큼 방대하다. 그러니 수학문제 풀듯이 계속 붙들고 있는건 미련한 짓이다. 이건 마치 덧셈,곱셈 정도만 아는 상태에서 미적문제를 푸려는 시도와 같다고 생각한다. 앞서 말했다시피 모르는 사람은 뭘 모르는지 모르는게 문제다. 본인이 미적에 대한 개념이 있는지 조차 모르는데 그 문제를 백날 붙들고 있어봐야 풀릴까? 당연히 아니다... 일단 1시간 넘어가면 그 문제 풀 확률은 거의 없다고 봐도 된다. 그러니 바로바로 찾아봐라. 특히 이 문제들은 정말 기초 문제들이고 사람들이 많이 풀었기 때문에 네이버나 구글에 검색하면 자세한 설명과 코드가 넘쳐난다.

 

반드시 지키자! 1시간 넘어가면 풀던 짓을 그만두고 반드시 AC받은 코드 찾아보기 (설명이 꼭 달려있는 코드를 읽자)

한 문제 가지고 며칠씩 씨름하고 풀어봐야 다음에 풀지도 못할뿐더러 아주 비효율적인 방법으로 푸는 경우도 있을 거다.

그러는 것 보다 이 문제의 답을 빨리 확인하고 이와 유사한 문제들을 여러개 풀어제끼는 것이 아주아주 현명한 방법임을 명심하자.

 

그리고 푼 다음에는 반드시 다른 사람의 코드를 봐야 한다.

특히 자신만의 가상의 스승을 잡고 그 분의 코드를 보는 것도 좋은 방법이라 생각한다.

너무 갓갓들은 이상한 방식으로도 짜는 경우도 있기 때문에 적당한 사람을 선택해야 한다.

그 사람의 코드를 보면 잘 이해가 되고, BOJ랭킹은 100위 안에 드는 사람이면 적당하다.

 

근데 처음부터 끝까지 하나하나 세밀하게 볼 필요는 없다.

로직 대충 비슷해보이면 스킵하고, 나랑 완전 다른 방법인데 참신하면 들여다보고 하는거지 뭐...

 

 

그 다음 이런 저런 문제들을 풀어보자.

2751, 11650, 11651, 10814, 10825, 10989, 11652, 11004, 10828, 9012, 10799, 10845, 10866, 10808, 10809, 10820, 2743, 11655, 10824, 11656, 1406, 1158, 1168, 10430, 2609, 1934, 1850, 9613, 11005, 2745, 1373, 1212, 2089, 11576, 1978, 1929, 6588, 11653, 10872, 1676, 2004

 

여기까지 다 풀고 나면 이제 재밌는 그래프 문제(bfs, dfs)를 풀어보자.

그래프 - 1260, 11724, 1707, 10451, 2331, 9466, 2667, 4963, 7576, 2178, 2146, 1991, 11725, 1167, 1967

 

코포(Codeforces) div2에서도 자주 등장하는 binary search 문제도 풀어보자. (여기엔 ternary search도 있다.)

이분탐색/삼분탐색 - 1654, 2805, 2110, 10815, 10816, 11662

 

분할정복도 풀어보자~

분할정복은 DP랑 느낌이 비슷한데, 부분 문제를 dp테이블에 저장할 필요가 없는(cache질을 할 필요가 없음) 부분이 DP랑 다른 것 같다.

분할정복 - 11728, 1780, 11729, 1992, 2447, 2448, 1517, 2261

 

그리디 알고리즘은 매 순간 최선을 선택한다라는 말 때문에 매우 쉽게 들리지만, 매 순간의 선택이 최선이 되도록 방법을 정하는 것 자체가 매우 어렵다.

그리디 - 11047, 2875, 10610, 1783, 1931, 11399, 2873, 1744

 

그 다음은 완전탐색(exhaustive search)이다.

완전탐색은 '말하는 대로' 구현하는 문제다.

그냥 무식하게 구현하면 될 것 같지만, 여기서도 고수의 코드를 보면 그들의 멋진 computational thinking 방식을 느낄 수 있다.

처음에는 이런 문제도 어렵지만 나중에는 쉬워진다.

이걸 실수없이 빠른 시간안에 잘 짜야 쉬운 문제들을 척척 풀어나갈 수 있다.

완전탐색 - 1476, 1107, 1451, 9095, 10819, 10971, 1697, 1963, 9019, 1525, 2251, 2186, 3108, 5014, 1759, 2580, 1987, 6603, 1182, 2003, 1806, 1644, 1261, 1208, 7453, 2632, 2143

 

여기까지 푸는게 딱 4주 분량이다. (BOJ 문제 부분만)

여기까지 푸는데 4주를 안넘기는게 좋다고 생각한다. 왜냐면, PS를 하면서 느낀건데, 단기간에 몰아서 왕창 할 수록 얻는 양은 어마어마하게 달라지는 것 같다.

보통 그리디 문제 전까지 2주를 잡고 그리디랑 완탐부분을 2주 잡으면 될거다. (그리디랑 완탐 양이 꽤 많다. 저 문제 다 풀기 정말 힘들다ㅠ)

 

이 정도 했으면 이제 종만북(알고리즘 문제 해결전략)을 보자.

(http://book.naver.com/bookdb/book_detail.nhn?bid=7058764)

 

2018.11.23 수정 - (원래 빨간책이란걸 추천했으나, 지금은 추천하지 않는다.)

 

나는 이 단계에 오기 전에 종만북 보는 것을 매우 비추한다.

물론 처음 부터 종만북보고 정말 잘하는 분들도 있지만, 종만북은 절대 초보자용이 아니다.

 

종만북 보면 어디어디 선택해서 보라고 나와있는데

나는 그것보다 1권 마지막 수치해석부터 읽는 것이 좋다고 생각한다. (어디까지나 개인적인 생각입니다.)

그리고 기하는 skip~!! 기하는 종만북 다 씹어먹을때 쯤 읽는 것을 추천한다.

 

그리고 2권에 나오는 그래프 부분이 정말 재밌다.

 

일단 이렇게 진도가 쭉쭉 나가야 뭘 하는 재미라도 있다.

그리고 2권 다 봤으면 1권 보면 된다.

(종만북 보면서 당연히 알고스팟 문제들 다 풀어봐야 한다.)

 

 

그 다음 노란책을 보자. (http://book.naver.com/bookdb/book_detail.nhn?bid=6750543)

이거 평점이 상당히 안좋은데, 번역이 안좋아서 그렇다.

그런데도 이 책을 추천하는 이유는, 여기까지 공부한 상태라면 오타랑 어색한 표현들이 그냥 다 보이기 때문이다.

 

노란책의 장점은 네트워크 플로우 부분이라 생각한다.

또 전체적으로 책이 매우 얇으면서도 있을건 다있고 정말 보면 볼 수록 갓책이라는 느낌이 든다.

특히 종만북은 네트워크 플로우 부분이 너무 없고 (Dinic, MCMF도 없고..)

문자열 파트도 처음 보고 이해하기가 좀 어려웠는데

그런 부분들을 노란책이 다 메꿔주는 것 같다.

 

어차피 노란책을 볼 때 쯤이면, 취업 걱정 할 일이 없을거고

시작하기 전의 나 자신을 돌아보면 참 많이 발전했다는 것을 느낄 수 있을 것이다.

 

그럼 이제 다시 아까의 질문들을 떠올려보자.

 

▶ 어디서부터 문제일까?

 어디부터 공부해야할까?

 어떤 문제를 풀어야 할까?

 도움은 어디서 받아야 할까?

 문제를 이렇게 오래잡고 있어도 될까?

 

요약한 답변은 아래와 같다.

 

▶ 어디서부터 문제일까? ☞ 내가 모르는게 뭔지 몰라서 문제다.

 모르는게 뭔지 어떻게 아냐? ☞ 문제풀면서 모르는걸 채워나간다. 책을 처음부터 보는 정공법이 아니라 기본문제를 풀면서 모르는 부분을 빠르게 채워 나가는 속성법이다. 다만, 반드시! 명심해야 할 것은 기초 입출력문제에서 10분이 넘어가면 반드시 모르는 부분이 있다는 것이다. 꼭! 잘하는 사람의 코드를 찾아보고, 속성법인 만큼 빠르게 모르는 것들을 캐치하고 정공법으로 돌아가야 한다.

 어디부터 공부해야할까? ☞ 언급한 BOJ문제를 풀고 종만북을 본다. 종만북 다 보고 나면 노란책으로 입가심을 하자.

 도움은 어디서 받아야 할까? ☞ 밑에 링크를 적었다. (BOJ Slack (분쟁이 있어서 사라진 것으로 앎. → dotorya님의 Discord를 이용)

 문제를 이렇게 오래잡고 있어도 될까? ☞ 입출력 문제를 제외하고 다른 문제들은 1시간으로 생각하자. 시간이 지나면 답을 보고 푼다.

  

물론 이러한 내용들은 사실 혼자 끙끙거리는 것 보다 강의를 듣는게 백배 낫다고 생각한다.

나도 백준 강의를 통해 해결했기 때문이다.

강의를 듣게 되면 위와 같은 방식으로 문제풀이를 진행하는데,

내가 백날 입출력은 10분 넘기면 모르는거라고 떠들어대도

막상 공부시작하는 사람들은

"에?! 뭐야 이거 입력하고 출력하는걸 뭐하러 해?"

"달력 출력은 시간낭비지 이걸 해서 얻는게 뭐지?"

라는 생각을 하고 그냥 넘기거나 대충하는 사람들이 있다.

 

입력받고 그냥 그대로 출력하는 문제는 30초,

날짜를 입력받고 요일을 출력하는 문제나 모두 3분 안에 코딩이 가능하다.

빠른 시간안에 코드를 짜지 못한다는건 결국 코드가 형편없다는 것을 의미한다.

빠른 시간안에 짤 수없는 방향으로 생각을 했기 때문에 코드가 빠르게 완성되지 못하는 것이다.

이걸 누군가 알려주지 않는다면 계속 우물안 개구리에 머물러 있을 확률이 높다.

이런 부분은 강의/선생님을 통해서 해결하는게 베스트이긴 하다.

 

당연히 내가 백준 강의 홍보대사를 맡은것도 아니고 그 분한테 광고비를 받는것도 아니다.

오프라인 강의가 비싸다면 온라인강의라도 듣는 것을 추천하지만,

온라인은 들어본적이 없으므로 판단은 본인 몫이다.

 

현재(2016년)는 강의마다 9만9천원에 올라와 있는데,

내가 듣는 것을 추천하는 온라인 강의는 기초,중급1,중급2 부분이다.

이게 오프라인 강의에서는 입출력부터 시작해서 네트워크 플로우 나오는 부분까지를 말한다. (아마 2달치로 구성되어 있을 것이다.)

 

내 생각엔 여기까지가 기초다.

왜냐하면 지식습득 부분까지는 기초라고 생각하기 때문이다.

오늘 무언가 알게되었을 때, 내일도 아는거고 모레도 아는거면,

그건 아무나 할 수 있는거니까..

 

아무튼 여기까지 하고나면 알고리즘이라는 거대한 숲을 보는 안목이 생기고

STL을 몰라서 헤매는 부분이 자연스럽게 해결된다.

안보이던 종만북도 쉽게 읽히고,

스스로 공부하는 데 무리가 없게 된다.

 

만약 강의에 거부감이 있다면,

처음에 언급했던 방법을 따르는 것을 추천한다.

 

그럼 다들 즐거운 PS 하시길~!

 

 

 

 

 

 


 

내가 자주 이용하는 사이트는 굵은색과 글씨크기로 중요도를 표시했다.

C++ Referencehttp://cppreference.com (www.cplusplus.com 거기보다 십만배 좋다고 생각하는 C++ reference 사이트다. 디자인도 좋고 훨씬 깔끔하고 훨씬 보기가 좋다.)

백준 온라인 강의: https://code.plus

백준 온라인 저지: https://boj.kr

알고스팟 종만북 문제집https://algospot.com/judge/problem/list/?tag=&source=알고리즘+문제+해결+전략&author=

정올 온라인 저지: http://www.jungol.co.kr

(정올 문제를 BOJ에서 풀다가 WA를 받은 경우 정올 가서 서밋해보면 틀린 테케를 확인할 수 있다. 다만, 문제 이름은 서로 다를 수 있으므로 출처를 통해 알아서 잘 찾아야 한다. ㅋ 테케는 BOJ가 다른 OJ보다 훨씬 센 편이다. 다른 곳에서 돌아가는 코드가 BOJ에서 안돌아가는 경우를 심심찮게 확인할 수 있는데, 보통 공식 테케가 허접한 경우일 때가 많다.)

더블릿: 단계별 학습으로 유명한데, 유료다. 알고스팟과 BOJ가 있는 마당에 돈을 내면서까지 이용해야 하는지는 잘 모르겠다.

koi4study: http://koistudy.net (유용한 자료가 많다. 특히 여기서 소개하는 hustoj가 있는데, 초딩도 쉽게 만들 수 있을만큼 설명이 되어있다. 나만의 OJ를 원한다면 첫 OJ로 경험하기엔 아주 딱인것 같다. 그리고 여기서 소개되는 두 선생님의 사이트가 있는데, 가보면 어린 친구들이 많은걸 볼 수 있다. 직접 이용을 하진 않아서 그 저지가 어떤지는 잘 모르겠다.)

BOJ Slack: https://www.acmicpc.net/board/view/2788 (여기서 슬렉 초대메일을 받을 수 있다. 초대 메일이 안보인다면 Junk Mail에 들어가 있을 수도 있으므로 잘 찾아볼 것. 갓들의 피드백을 바로바로 받을 수 있다. 여기가 아니었다면 내가 PS를 1년가까이 지속해서 할 수 있었을까?? 나를 지탱해준 힘은 여기인듯 하다.) BOJ Slack은 폭파되었다고 한다. 대체 커뮤니티로는 dotorya님이 운영하는 디스코드가 있다. BOJ 랭킹을 검색해보면 디스코드 적혀있을 것이다.

 

 

외국 온라인 저지

코드포스http://codeforces.com (국내에서 가장 많이 이용하는 외국 사이트가 아닐까?)

탑코더: https://community.topcoder.com/contest/arena/ContestAppletProd.jnlp (링크 누르면 다운로드가 된다.)

탑코더 공식 홈페이지에 들어가보면 뭔가 그럴싸하게 보이지만, 만들다 만거라고 보면 된다. ps분야 말고도 이거저거 하는게 많은데, 다른 분야는 모르겠고 ps arena에 들어가보면 beta버전이라고 되어있는데 내가 알기로 여기선 뭔가 contest를 진행할 수가 없다. 다들 위의 경로에서 다운받은 옛날 스타크래프 배틀넷 같이 생긴 어플을 통해 콘테스트를 치룬다. 와 정말 점점 느끼는 거지만 BOJ만큼 현대적인 인터페이스를 제공하는 온라인 저지가 없다. 코포도 보면 가관일때가 있다.(하다보면 앎) 아무튼 탑코더는 해보면 아는데, 희한하게 문제에서 제시한 조건에 맞는 클래스를 생성해서 제출해야 하며 스타 배장같이 생긴 arena에서 코딩 맞짱을 뜨는 느낌이 든다.

uvaojhttps://uva.onlinejudge.org (acm-icpc 출제자들이 여기서 문제를 냈다는거 같은데, 엄청 오래됐고 엄청 유명한 사이트다. 웹 UI는 극악이다. 해보면 안다. 여기가 워스트라고 생각 됨) ☞ 그래서 반드시 https://uhunt.onlinejudge.org 사이트가 병행된다. uvaoj를 쓸 수 있게끔 해주는 필수 사이트!

poj: http://poj.org (북경대 온라인저지: 노란책때문에 처음 알게 됐는데, 이 저지도 상당히 유명하다.)

spoj: http://www.spoj.com (이런 저지도 있다.)

a2oj: https://a2oj.com (여기 가면 해외 유명 온라인 저지랑 전부 연동이 가능하다. 여기서 보여주는 저지들이 아마 해외에서 제일 유명한 저지들이 아닐까 싶다.)

 

 

요즘 내가 들어가는 사이트 순서대로 글자 크기와 Bold체를 써서 나태내봤다.

눈에 띄는 정도가 중요도 순서라고 봐도 무방하다.

'PS - OJ > BOJ' 카테고리의 다른 글

BOJ 14265 영선 수열  (0) 2017.01.14
1280 나무심기  (0) 2016.12.26
1328 고층빌딩  (0) 2016.12.09
13333 Q-인덱스 (Q-Index)  (0) 2016.12.09
8217 유성 (Meteors)  (0) 2016.11.19