[알고리즘 공부팁] 2. 각자에게 맞는 유형 찾기

[알고리즘 공부팁] 2. 각자에게 맞는 유형 찾기
Photo by Kelly Sikkema / Unsplash

알고리즘을 공부하는 타입에는 다음과 같은 타입이 있습니다. 조금 전문적이지 못한 표현이 있을 수 있으나 이해를 위한 단어이므로 이해 부탁드립니다. 제가 본 몇 부류에 의하면 다음과 같이 분류할 수 있습니다.

이번에도 언급하고 싶은 부분은 잘하시는 분(코드포스 보라 이상)들은 허허 웃으면서 넘어가주시면 좋겠습니다. 왜냐면 저는 이미 잘하시는 분들에게는 공부 방법을 추천해드릴 수가 없습니다. :-(

저는 일부 공부 방법을 유형별로 나눴고, 각각의 특징을 조금 작성해봤습니다. 특정 형태가 정해진 사람은 많이 없으니 전체적인 팁으로 생각하면 좋을 것 같습니다. 핵심은 4개를 잘 병행해가며 공부하는 것이 가장 좋습니다. 공부는 다다익선이죠.

  • 랭킹작
    • 시리즈로 미는 경우
  • 암기와 이해
  • 멘토-멘티 / 라이벌 ⇒ 스터디
  • 대회형

번외로 다음과 같은 부류도 있습니다.

  • 재능형 : 재능이 출중하여 부러움을 사는 존재들. 넘을 생각보다는 존경할 생각하는 것을 추천한다.
  • 군인형 : 군대에서 남는 틈새 시간을 활용한 분들로 의지가 뛰어나 실력이 증가하는 경우가 꽤 있다.
  • 주제 특화형 : 구현 능력, 수학 능력 등에 초점을 두는 분들이 있다. 그냥 무섭다.

한 번 하나씩 이야기 해보겠습니다. 어느 것이 좋다고는 할 수 없습니다. 어떤 식으로 이것들을 결합하여 자신만의 스타일을 찾아갈 지 고민해보는 것을 추천합니다.

랭킹작

어디서부터 이 단어가 나왔는지는 모르겠습니다. 사이트에서 랭킹을 높이기 위해 문제를 많이 푸는 것을 의미하고, 흔히 랭작이라고 불립니다. 여기서는 일단 많이 푸는 유형을 의미합니다.

꽤 주변에서 많이 볼 수 있고, 대표적인 예시가 저(subinium) 입니다. 이 부분은 저의 예시를 통해 장단점, 그리고 보완 방법을 제안하고자 합니다.

이 방법은 문제를 푸는 유형에 따라 다르지만 다음과 같은 장점을 가집니다.

  • 많은 문제를 풀기 위해 본인 수준에서 쉬운 문제를 위주로 풀게 됩니다.
    • 많은 구현을 하게 되며 언어 자체가 익숙해집니다.
    • 구현 속도가 빨라집니다. 결국에는 전체적인 속도가 빨라집니다.
    • 문제를 읽고, 이해하는 능력이 빨라집니다. 어느 순간부터는 문제보다 입력을 보고 알고리즘의 후보군을 세울 수 있습니다.
  • 쉬운 문제의 범위를 조금씩 커버해가며, 점차 어려운 문제만 남게 됩니다. 즉 점진적으로 실력이 늡니다.
  • 사이트 랭킹이 늘기 때문에 계속적으로 목표가 생깁니다. 대회보다 쉽고 편한 목표입니다.
    • PS계에서 자존감을 높일 수 있는 하나의 방법입니다.
    • 하지만 이 자존감이 그리 오래 가지 않았다는 게 제 감상평입니다.

하지만 다음과 같은 단점이 존재합니다.

  • 스스로가 문제를 많이 못푸는 수준이 오면 급격하게 피로해집니다.
  • 투자 시간, 문제 양에 비해 가장 중요한 문제 해결 능력 성장이 느립니다. 이 또한 피로합니다.
  • 쉬운 문제를 위주로 풀기에 알고리즘 공부에 소홀해질 수 있습니다.
  • 쉬운 문제를 위주로 풀기에 긴 코드, 약 2000B를 넘어가는 코드 작성의 경험이 부족합니다.
    • 대회를 진행하다보면 코드의 양이 매우 길어질 때가 있습니다. 이에 대한 연습도 필요한 부분입니다.
  • 랭킹을 높이기 위해 풀이에 대한 의존도가 높아질 수 있고, cheating 유혹이 커지는 순간이 옵니다.

랭킹만을 위한 공부는 절대 비추입니다. 실력이 되면 어느 순간부터는 속도가 붙고 랭킹은 쉽게 높일 수 있습니다.

그렇기에 이 방법은 초보자, 즉 아직 프로그래밍 언어가 손에 익지 않고, STL 사용, 자료구조 및 알고리즘의 이해가 부족한 분들에게 추천합니다. 더 효율적인 방법에는 다음과 같은 방법을 추천합니다.

초급

초보자분들에게 추천하는 공부법이기도 하며, 그렇기에 주의해야할 점이 많습니다.

  • Ctrl+C,V의 사용과 자동완성을 줄일 것. 쉬운 문제는 단순하여 지난 번 코드를 사용하고 싶을 때가 많습니다. 하지만 구현 연습 단계에서는 최대한 그 언어를 이해하는 것을 추천합니다. 어떤 환경에서 코딩할지는 모르는 거니까요.
  • 구현 문제는 다음 3개 정도의 소스를 추천합니다.
  • 자료구조와 알고리즘 공부를 소홀히 하지 마세요. 또한 구현을 하면서 보다 효율적인 방법에 대해서 계속 고민해야합니다.
    • 예를 들면 brute-force(전수조사, 모든 경우를 다해보는 것)말고 수식으로 1번에 되는 결과는 없을까.
    • 효율적인 방법으로 저장할 수는 없을까
    • min, max 등의 기본적인 함수는 STL을 사용해보기
  • 반드시 필요한 자료구조는 양이 적습니다. 좋은 글이 많으니 조금씩 읽어보세요.
  • 초보자의 단계에서는 고민하는 시간이 많은 것도 중요합니다. 코드로 바로 풀이를 보는 것보다는 글로 풀이를 읽고 구현하는 시간을 가져야 합니다. 코드를 안보고 짜는 연습을 해야합니다.
  • 다양한 자료를 보는 것보다는 책 또는 좋은 자료 하나의 의미를 이해하고자 노력하는 것이 중요합니다.

중급

  • 구현이 부족하신 분들은 원하는 문제로 랭작을 하시면 됩니다.
  • 하지만 효율적인 랭작은 언제나 추천하듯 다음과 같습니다.
    • USACO https://www.acmicpc.net/category/106
    • USACO 공식 사이트(에는 풀이가 있습니다.) USACO 2019 US Open Contest , Bronze 1과 같이 대회 정보, 연도, 난이도, 번호를 함께 입력하면 사이트(풀이)를 잘 찾아줍니다.
    • 한국정보올림피아드
    • 문제 수가 많고, 풀이를 찾을 수 있으며, 난이도도 어느정도 분류가 잘 되어있습니다. 가이드라인에 따라 문제를 만들기 때문에 필요한 알고리즘 지식을 습득할 수 있습니다.
  • 코드를 길게 작성하는 게 싫으신 분들은 수학 문제를 위주로 랭작을 하며 수학적 사고력을 계속 키우는 것도 하나의 팁입니다.
    • 개인적으로는 Waterloo 대회 문제를 푸는 것을 추천합니다.
  • 빠르게 풀고 싶은 분들은 매크로 함수 등의 빠른 코딩 방법을 익히는 것도 하나의 방법입니다.
    • 저는 이 방법을 매우 싫어하나 이 방법을 익히면 CP면에서는 충분히 좋은 기능을 합니다.
    • 이 부분은 나중에 따로 글로 작성하겠습니다.

제가 글을 시작하기 전에 시리즈로 민다는 표현을 썼는데, 이는 USACO와 같이 목표를 잡고 문제를 푸는 것을 의미합니다. 랭작과는 거리가 멀지만 여러 방법으로 특정 부분의 실력을 보완시킬 수 있는 부분입니다. 예시로는 다음과 같은 주제가 있습니다.

  • 아이디어를 수준급으로 기를려면 : POI (폴란드 정보 올림피아드)
  • 수학적 아이디어는 : AtCoder, Project Euler
  • 전형적인 문제는 : USACO
  • ICPC 대회 특화 : ICPC 기출들

암기형과 이해형

비슷하면서도 다른 형태의 유형입니다.

  • 암기형 : 코드나 유형을 그냥 암기한 후에 문제에 적용한다.
  • 이해형 : 이해를 하기 전까지는 넘어가지 않는다.

사실 암기형은 부러운 형태의 유형입니다. 저는 암기 능력이 매우 부족하기 때문입니다. 그렇기에 시험에서도 정의를 묻는 문제가 나오면 거의 하위권 점수를 받고는 합니다.

암기형은 여러 장점이 있습니다. 주변에 암기가 강한 대단한 친구가 있는데 장점은 확실히 있습니다.

  • 본인만의 틀을 갖추면 그 후에는 그 양식을 그대로 쓸 수 있다.
  • 결국 문제는 유사한 유형에서 나오므로 외운 것을 기억할 수만 있다면 상위권은 쉽다.

하지만 당연히 단점도 중요합니다. 물론 그 친구는 암기 뿐만이 아니라 다 열심히 해서 보완된 친구입니다.

  • 암기 속도가 느린 경우, 본인 역량의 부족이 큰 이유가 될 수 있습니다.
    • 암기에 초점을 두면 시간 소모가 큽니다.
  • 유형이 변하는 경우, 적용을 못할 수가 있습니다. 이것은 연습 부족이니 연습이 답입니다.
  • 알고리즘의 재미가 없습니다. 동기부여가 적은 방법이죠.
  • 알고리즘이 주가 아닌 아이디어나 수학이 강조되는 대회에 취약합니다.
    • 구글 코드잼 등이 아이디어 문제가 더 많은 경향성이 있습니다.

암기를 위주로 공부하시는 분들에게는 다음과 같은 유형의 공부 방법을 추천합니다.

  • 체크리스트를 만들어 본인이 필요한 알고리즘이 무엇인지 체크하는 것도 좋습니다.
  • 본인만의 코드 스타일이 제일 중요합니다.
  • 잘하는 분들의 코드를 많이 보세요.
    • 좋은 블로그를 읽는 것이 중요합니다. 제가 가장 많이 도움을 받고 코드 유형을 배울 수 있었던 블로그는 다음과 같습니다. 내용도 좋고 코드 스타일도 좋아합니다. 전 후자에서 매우 많이 배웠습니다.
    • 코드포스에서 대회 참가 후, 고수분들의 코드를 보는 것도 추천합니다.
  • 암기한 코드를 계속 본인의 스타일대로 코딩해보는 것이 중요합니다. 같은 문제라도 반복해서 풀어보는 것을 추천합니다.
  • 여러 유형을 접하며 다양한 스타일을 암기하는 것을 추천합니다. 아이디어는 암기보다는 문제의 재미를 느끼고 공부할 때 더 많이 떠오르는 것 같습니다.

이해형은 이해가 안되면 안넘어가는 분들을 이야기합니다.

이해형은 개인적으로는 선호하지 않습니다. 하지만 이해는 분명 좋은 방법입니다.

  • 이해를 한다는 것은 머리로 구조화가 완료되었다는 뜻입니다.
    • 암기가 빨라지고, 코드를 까먹어도 즉시 복구할 수 있습니다.
    • 오래 기억할 수 있습니다.
  • 이해를 하면 생각의 폭이 넓어집니다. 알고리즘 간의 관계, 새로운 방법론 등을 떠올릴 수 있습니다.

하지만 가장 큰 단점이 있습니다.

  • 보통 오래 걸립니다. 오래 걸린다는 것은 열정이 식는 시간이 지속되는 것입니다. 이해를 하다 포기하는 순간, 흐름이 깨질 수 있습니다.

이런 분들에게는 다음과 같은 방법을 추천합니다.

  • 이해에는 단계가 있습니다. 책 커리큘럼이나 여러 로드맵을 보고 이해가 안되면 앞의 내용을 다시 살피는 방법을 추천합니다. 앞의 내용에서 부족한 이해가 있을 수 있습니다.
  • 이해를 반드시 문서로 할 필요는 없습니다. 코드 자체로 이해하는 연습도 병행하는 것을 추천합니다. 코드를 머릿속에 구조화하는 과정이 꽤나 좋습니다.
  • 직관적으로 이해가 어려운 문제가 있습니다. 이는 포기하고 적용부터 우선하는 것을 추천합니다.
  • 수학의 이해가 어렵다면, 정수론, 경우의 수, 확률 등을 먼저 공부하는 것도 추천합니다.

멘토와 멘티 / 라이벌 ⇒ 스터디

사실 이 방법보다 좋은 방법은 보지 못했습니다. 가장 좋은 것은 나를 이끌어줄 수 있고, 내가 목표하는 방향에 더 가깝게 갈 수 있는 멘토를 찾는 것입니다.

학원이라면 선생님, 동아리라면 실력있는 동아리 구성원, 등등 입니다. 멘토와 멘티의 장점은 다음과 같습니다.

  • 멘토는 더 효율적인 설명을 위해 노력하며 알고리즘에 대한 이해를 높일 수 있습니다.
    • 알고리즘 base가 더 단단해지는 과정입니다.
  • 멘티는 즉각적으로 모르는 부분을 채우며 빠르게 성장할 수 있습니다.
  • 둘 다 성장할 수 있는 방법입니다.

단점이 있다면, 좋은 멘토를 자청하는 사람은 부족합니다. 돈과 시간을 투자해서 얻을 수 있는 부분이 매우 적기 때문입니다. 하지만 종종 그런 일을 해주는 분들이 있습니다. 멘티의 노력으로도 그런 분을 만날 수 있습니다.

이에 대한 팁은 다음과 같습니다.

  • 멘토는 정답을 주지 말고, 멘티는 최대한 멘토에게서 정보를 끌어내려고 노력해라.
    • 그렇다고 멘티가 일방적으로 멘토에게 의지하라는 의미는 아닙니다.
    • 가장 좋은 것은 방향을 제시하고, 자립성을 키우게 도와주는 것이 제일 중요합니다.

이 와 유사하게 라이벌이 있습니다. 라이벌이 있다는 것은 매우 좋은 방법입니다.

저는 경쟁을 좋아하지 않지만, 열심히 하게 된 이유 중 하나는 친구와의 경쟁이었습니다.

(비슷한 수준의) 라이벌은 다음과 같은 장점을 가지고 있습니다.

  • 동기부여가 잘된다. 지지 않기 위해 더 열심히하고 즐겁게 할 수 있습니다.
    • 서로 긍정적인 영향을 미칩니다.
  • 서로의 장단점을 파악하며, 채워야 할 부분을 빠르게 알 수 있습니다.
  • 이런 라이벌은 후에 당신의 팀원이 될 수도 있습니다.

단점이 있다면 ...

  • 지나친 경쟁은 심신에 안좋습니다. 건강에 무리가 오는 경우도 생깁니다.
  • 서로 기분 나쁜 일은 하지 맙시다.
    • 굳이 상대방이 푼 문제를 따라 풀기

멘토와 멘티 그리고 라이벌의 관계가 번갈아가며 경험할 수 있는 곳이 스터디입니다. 스터디를 통해 위 장점과 집중, 꾸준함 등을 함께 챙기는 것도 좋은 방법입니다.

스터디 진행의 장점 중 하나는 문제를 선별하며, 문제(퀄리티)를 보는 눈이 높아진다는 장점이 있습니다.

대회형

Motivation, 동기가 중요한 분들에게는 대회만큼 좋은 목표는 거의 없습니다. CP 그 자체이기도 합니다.

대회는 심신에 피로를 주지만, 그만큼 환기를 주는 도구입니다.

장점은 다음과 같습니다.

  • 동기부여가 된다.
  • (잘하면) 실적이 남는다.
  • 알고리즘 트렌드를 알 수 있다.
  • 본인의 위치를 지속적으로 파악할 수 있다.

단점은 다음과 같습니다.

  • 심신이 지친다.
    • 자주 참가할 수 있는 대회의 대부분의 온라인 대회는 외국에서 진행되므로 시간대가 안맞아서 생활주기가 엉킬 수 있다. 즉 학부생 중 오전 수업이 없거나 포기한 자들만 편하게 가능하다.
  • 본인 위치 파악은 사실 성장에 큰 도움을 줄 수 없다. 결론은 업솔빙(지난 문제를 다시 풀어보는 과정을 의미)을 해야만 의미가 있다.

이런 분들은 제가 드릴 수 있는 팁은 별로 없습니다.

  • 문제를 영어로 빨리 읽는 것이 필요합니다.
    • 영어 실력이 곧 점수에 반영됩니다.
  • 대회의 rating에 연연하지 않기 위해 노력하세요.

코드포스 및 CP/PS를 잘하기 위해 연습하는 방법에 대한 글을 추천 하고자 합니다. 이 글은 몇 번 읽어도 좋은 글입니다.

글 읽기 - 코드포스 오렌지~레드 이상이 되기 위해선 어떤 공부 방식이 도움이 많이 될까요?