출처:  http://usaco.org/index.php?page=viewproblem2&cpid=1180


문제 설명

4면체 주사위 3개(A, B, C) 가 있고, 주사위의 각 면의 숫자는 1부터 10 사이의 숫자이다. 두 주사위를 던져서 높은 숫자가 많이 나오는 주사위가 이겼다고 할때, A > B > C > A 혹은 A < B < C < A 가 되는 조합이 있는지 판별하는 문제이다. 입력으로는 주사위 A, B의 숫자들이 주어진다.

입력

3
4 5 6 7 2 4 5 10
2 2 2 2 1 1 1 1
1 1 1 1 2 2 2 2

출력

yes
no
no

 


문제 풀이

주사위 C의 숫자들이 1 ~ 10 이고, 4개의 숫자를 선택할때 가능한 모든 조합 O(N^4)를 해도 10^4 이고, 주사위 2개를 비교해서 편정하는 경우도 4^2 이므로, 전체 계산량은 대략 10^5 정도로 가능하다. 중첩된 Loop 로 모든 경우를 비교하는 알고리즘으로 가능하다. 

프로그램 내용

더보기
...
for(i)
	for(j)
    	for(k)
        	for(l)
            	dice_c = {i, j, k, l}
                if( dice_c >dice_b && dice_b >dice_a && dice_a > dice_c)
                	flag = true; break;
				if( dice_b >dice_c && dice_a >dice_b && dice_c > dice_a)
                	flag = true; break;
if(flag)
	cout << "yes"
else
	cout << "no"

 

'USACO' 카테고리의 다른 글

USACO 2022 January Bronze Problem 1  (0) 2022.02.04

출처: 2022 January Bronze Problem 1 ( link )


문제 설명

3X3 charater puzzle

- Green: correct

- Yellow: Mis location

입력 1

COW
SAY
MOO
WIN
THE
IOI

출력

1

1

입력 2

AAA
BBB
CCC
AYY
AAA
ZZZ

출력 

1

2


문제 풀이

문자열 비교를 어떻게 할 것인가 하는 문제이다. 입력으로 주어진 3 x 3 퍼즐을 1 x 9 형태로 바꿔도 문제 풀이에 영향은 없다. char[9] 인 두개의 배열/vector를 만들어서 예상 답안과 실제 답안을 입력하고, 전체를 비교해서 같으면 Green 값에 반영한다.  다음은, 두 답안의 A~Z의 빈도를 확인해서, 잘못된 위치지만 있었는지 확인해서 Yellow 값에 반영한다. 다만, Green 에 반영된 결과를 두번 세지 않도록 해줘야 한다.

프로그램 내용

더보기
// serialization & count frequency 

	for(int i = 0; i<3; ++i)
    {
        string tmp;
        cin >> tmp;
        ans += tmp;
        ans_cnt[tmp[0]-'A']++;
        ans_cnt[tmp[1]-'A']++;
        ans_cnt[tmp[2]-'A']++;
    }
    
    for(int i = 0; i<3; ++i)
    {
        string tmp;
        cin >> tmp;
        gus += tmp;
        gus_cnt[tmp[0]-'A']++;
        gus_cnt[tmp[1]-'A']++;
        gus_cnt[tmp[2]-'A']++;
    }

// cnt_g & cnt_y
    for(int i = 0; i<9; ++i)
    {
        if(ans[i] == gus[i])
            cnt_g++;
    }

    for(int i = 0; i<26; ++i)
    {
        cnt_y += min(ans_cnt[i],gus_cnt[i]);
    }

    cnt_y -= cnt_g;

 

'USACO' 카테고리의 다른 글

USACO 2022 January Bronze Problem 2  (0) 2022.02.21

출처: https://train.usaco.org/usacogate


문제 설명

출처 : IOI'96 - Problem 5

...

The first K characters of S are the prefix of S with length K. 

Write a program which accepts as input a set of primitives and a sequence of constituents and then computes the length of the longest prefix that can be composed from primitives. 

입력

First, the input file contains the list (length 1..200) of primitives (length 1..10) expressed as a series of space-separated strings of uppercase characters on one or more lines.

The list of primitives is terminated by a line that contains nothing more than a period (`.').

No primitive appears twice in the list.

 

Then, the input file contains a sequence S (length 1..200,000) expressed as one or more lines, none of which exceeds 76 letters in length.

 

The "newlines" (line terminators) are not part of the string S.

출력

A single line containing an integer that is the length of the longest prefix that can be composed from the set P.

입력 예

A AB BA CA BBC
.
ABABACABAABC

출력 예

11


문제 풀이

만들려고 하는 문자열 길이의 앞에서 부터 출발해서, 부분 문자열이 존재하는지 검사한다. 단순 double loop를 적용해도 부분 문자열의 수를 N, 만들려고 하는 문자열의 길이를 M이라고 하면 O(NM) 정도로 해결가능해진다.

프로그램 내용

더보기
... 
	// string target;
	// vector<string> primitives;
    
	dp[0]=1;
	for(int i=0;i< target.size();i++) 
	{
        if(dp[i])
        { 
            for(int j=0;j<primivites.size();j++) 
            {
                if( primivies[j]==target.substr(i,primitives[j].size()) ) 
                {
                    dp[i+primivies[j].size()] = 1;
                }
            }
        }
    }
    ...

 

Chapter 2. Bigger Challenges ( link

'USACO Training' 카테고리의 다른 글

Problem 2.2.3 Preface Numbering  (0) 2021.01.21
Problem 2.1.3 The Castle  (0) 2021.01.07
Problem 2.1.7 Hamming Codes  (0) 2021.01.06
Problem 1.2.5 Greedy Gift Givers - 2  (0) 2021.01.03
Problem 2.1.6 Healthy Holsteins  (0) 2020.02.11

출처: https://train.usaco.org/usacogate


문제 설명

Given N (1 <= N < 3,500), the number of pages in the preface of a book, calculate and print the number of I's, V's, etc. (in order from lowest to highest) required to typeset all the page numbers (in Roman numerals) from 1 through N. 

Do not print letters that do not appear in the page numbers specified.

입력

A single line containing the integer N.

출력

The output lines specify, in ascending order of Roman numeral letters, the letter, a single space,
and the number of times that letter appears on preface page numbers. Stop printing letter totals
after printing the highest value letter used to form preface numbers in the specified set.

입력 예

5

출력 예

I 7
V 2

( I, II, III, IV, V) -> I: 1(1)+2(2)+3(3)+1(4) = 7, V : 1(4) + 1(5) = 2


문제 풀이

1 부터 입력받은 숫자까지 Roman 숫자로 표현할때 각 숫자들이 몇번 나오는지 세는 프로그램을 작성한다.

Roman 숫자표현에서 나오는 문자는 7가지 이다.( I - 1, V - 5, X - 10, L - 50, C - 100 , D - 500, M - 1000) 

이런 7개 문자들이 몇번 나오는지 unordered_map<char, int> 형태로 기록한다.

프로그램 내용

더보기

 

...
	string ones[9] = {"I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"};
    string tens[9] = {"X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC"};
    string hundreds[9] = {"C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM"};
    string thousands[3] = {"M", "MM", "MMM"};
...
    unordered_map<char, int> m;
    for (int i = 1; i <= N; i++) {
        int num = i;
        
        if (num / 1000 > 0) {
            count(m, thousands[num / 1000 - 1]);
            num %= 1000;
        }
        if (num / 100 > 0) {
            count(m, hundreds[num / 100 - 1]);
            num %= 100;
        }
        if (num / 10 > 0) {
            count(m, tens[num / 10 - 1]);
            num %= 10;
        }
        if (num > 0) {
            count(m, ones[num - 1]);
        }
    }
    if (m.find('I') != m.end()) fout << "I " << m['I'] << endl;
    if (m.find('V') != m.end()) fout << "V " << m['V'] << endl;
    if (m.find('X') != m.end()) fout << "X " << m['X'] << endl;
    if (m.find('L') != m.end()) fout << "L " << m['L'] << endl;
    if (m.find('C') != m.end()) fout << "C " << m['C'] << endl;
    if (m.find('D') != m.end()) fout << "D " << m['D'] << endl;
    if (m.find('M') != m.end()) fout << "M " << m['M'] << endl;
...

 

Chapter 2. Bigger Challenges ( link )

'USACO Training' 카테고리의 다른 글

Section 2.3.1 Prob The Longest Prefix  (0) 2021.04.01
Problem 2.1.3 The Castle  (0) 2021.01.07
Problem 2.1.7 Hamming Codes  (0) 2021.01.06
Problem 1.2.5 Greedy Gift Givers - 2  (0) 2021.01.03
Problem 2.1.6 Healthy Holsteins  (0) 2020.02.11

출처: https://train.usaco.org/usacogate


문제 설명

The castle floorplan is divided into M (wide) by N (1 <=M,N<=50) square modules. Each such module can have between zero and four walls. Castles always have walls on their "outer edges" to keep out the wind and rain.

 

입력

Line 1: Two space-separated integers: M and N
Line 2..: M x N integers, several per line.

출력

Line 1: The number of rooms the castle has.
Line 2: The size of the largest room
Line 3: The size of the largest room creatable by removing one wall
Line 4: The single wall to remove to make the largest room possible

입력 예

7 4
11 6 11 6 3 10 6
7 9 6 13 5 15 5
1 10 12 7 13 7 5
13 11 10 8 10 12 13

출력 예

5
9
16
4 1 E


문제 풀이

IOI'94 - Day 1 의 문제이다. N x M maze에서 연결된 방들을 채워가는 Flood fill 알고리즘을 적용하면, 전체 연결된 방을 알 수 있다. 한방에서 연결된 방을 찾아가는 방법은 DFS가 적용된다.  N x M maze를 다루는 연습이 필요한 문제이다. 벽을 제거하면서 값을 비교할때는 항상 계산이 끝난 다음 원래 값으로 변경시키는 과정을 적용해야 한다.

프로그램 내용

더보기
void fill_cells(int y, int x, int& direction)
{
    if(visited[y][x]) return;
    visited[y][x] = 1;
    before[y][x] = roomNumber;
    direction++;

    if(!(cells[y][x] & 1)) fill_cells(y,x-1, direction); /// Connected Direction: W
    if(!(cells[y][x] & 2)) fill_cells(y-1,x, direction); /// Connected Direction: N
    if(!(cells[y][x] & 4)) fill_cells(y,x+1, direction); /// Connected Direction: E
    if(!(cells[y][x] & 8)) fill_cells(y+1,x, direction); /// Connected Direction: S
};
...

한 방에 도착하면 연결된 벽을 확인하고, 벽으로 막혀 있지 않으면 그 방까지 연결한다.

 /// visit every rooms
    for(int y=1; y <N+1; ++y)
    {
        for(int x=1; x<M+1;++x)
        {
            if(!visited[y][x])
            {
                roomNumber++;
                int tn=0;
                fill_cells(y,x,tn);
                room[roomNumber] = tn;
                if( tn > maxn ) maxn = tn;
            }
        }
    }

    /// remove wall check
    for(int j=1;j<=M;j+=1)
    {
        for(int i=N;i>=1;i-=1)
        {
            if(cells[i][j]&2)if(before[i-1][j] && before[i-1][j]!=before[i][j])
            {
                if( room[before[i-1][j]] + room[before[i][j]] > max2n )
                {
                    max2n = room[before[i-1][j]] + room[before[i][j]];
                    wx = i,wy = j,wd = 'N';
                }
            }

            if(cells[i][j]&4)if(before[i][j+1] && before[i][j+1]!=before[i][j])
            {
                if( room[before[i][j+1]] + room[before[i][j]] > max2n )
                {
                    max2n = room[before[i][j+1]] + room[before[i][j]];
                    wx = i,wy = j,wd = 'E';
                }
            }
        }
    }

전체 방에 대해서 벽을 제거해서 결과값이 최대가 될때마다 제거하는 벽을 기록하는 방법을 적용한다.

 

Chapter 2. Bigger Challenges ( link )

'USACO Training' 카테고리의 다른 글

Section 2.3.1 Prob The Longest Prefix  (0) 2021.04.01
Problem 2.2.3 Preface Numbering  (0) 2021.01.21
Problem 2.1.7 Hamming Codes  (0) 2021.01.06
Problem 1.2.5 Greedy Gift Givers - 2  (0) 2021.01.03
Problem 2.1.6 Healthy Holsteins  (0) 2020.02.11

출처: https://train.usaco.org/usacogate


문제 설명

Given N, B, and D: Find a set of N codewords (1 <= N <= 64), each of length B bits (1 <= B <= 8),
such that each of the codewords is at least Hamming distance of D (1 <= D <= 7) away from each
of the other codewords.

입력

N, B, D on a single line

출력

N codewords, sorted, in decimal, ten per line.

입력 예

16 7 3

출력 예

0 7 25 30 42 45 51 52 75 76
82 85 97 102 120 127


문제 풀이

Hamming Distance 계산하는 방법에 대한 문제이다. 각각의 bit 값을 비교하기 위해서, 2로 계속 나누고 달라질때마다 distance를 증가시키는 방법으로 계산한다. 0 부터 숫자를 키워가면서 distance > D인 경우들을 계속 추가시켜서 기록하고, 출력할때 10개 단위로 출력한다.

프로그램 내용

더보기
int getHammingDistance(int a, int b)
{
    int ret=0;

    while( a> 0 || b>0)
    {
        if( a%2 != b%2)
            ret++;
        a /= 2;
        b /= 2;
    }
    return ret;
};

...

  ans.push_back(0);
    /// check hamming distance > D, put result
    for(int i=0;i < maxB ;i++)
    {
        bool ok= true;

        /// compare hamming distance with last code
        for(int j=0;j!=ans.size();j++)
        {
            /// distance < D
            if( getHammingDistance(i,ans[j]) < D )
            {
                ok = false;
                break;
            }
        }
        /// distance >= D
        if(ok)
        {
            ans.push_back(i);
        }

        /// Max output number
        if(ans.size() >= N)
        {
                break;
        }
    }

 

Chapter 2. Bigger Challenges ( link )

'USACO Training' 카테고리의 다른 글

Problem 2.2.3 Preface Numbering  (0) 2021.01.21
Problem 2.1.3 The Castle  (0) 2021.01.07
Problem 1.2.5 Greedy Gift Givers - 2  (0) 2021.01.03
Problem 2.1.6 Healthy Holsteins  (0) 2020.02.11
USACO Training - Chapter 6. Contest Practice  (0) 2020.01.01

Competitive Programming (CP) 혹은 USACO 공부방법은 외국어를 배우거나, 운동을 배우고 훈련하는 것에 더 가깝다. 머리속에 지식(knowledge)을 쌓는 것보다 직접 작성할 수 있는 기술(skill)을 습득하는 과정이다.

 

여러가지 Blog나 참고 문서들이 있다.

  1. USACO Resource page ( link )
  2. Crash Course Coding Companion ( link )
  3. General Resources for Competitive Programming ( link )
  4. Beginner (Bronze/Silver) December Contest Prep ( link )
  5. A Way to Practice Competitive Programming : From rating 1000 to 2000 ( link )

먼저, 확인해야 할 것은 CP 는 Coding Competition이 아니라 Problem Solving Competition이라는 것이다. 실제로 문제 해결과정에서 implementation이 필요 없는 것은 아니지만, 전체 문제 풀이를 10이라고 할때 구현이 차지하는 부분은 2~3 정도가 된다고 생각한다. 정확한 문제의 이해가 전체의 1/3은 차지한다. 정확한 문제의 이해는 입력과 출력의 경계를 명확하게 하고, 알고리즘 구현과정에서 주의해야 하는 부분들을 찾을 수 있게 해준다. 예를 들어 문제 풀이 과정중에 덧셈이 있고 그 덧셈값을 어떤 변수에 저장하는 알고리즘을 생각해보자. 이때, 더하는 값들의 범위와 더한 결과 값을 기록하는 변수의 범위는 달라 질 수 있다는 것을 구현하기 전에 정리하는 것이 문제의 이해 과정에 얻어지는 것이라고 할 수 있다. 그 문제 이해를 기반으로 알고 있는 알고리즘에서 구현할 수 있는 것을 문제의 답안으로 할 수  있다. 대부분의 프로그래머들처럼 문제가 생겼을때 검색을 하거나 관련 자료를 찾아서 살펴볼 수 없다. 물론, 그정도의 자료조사나 연구가 필요한 문제는 일반적인 CP의 범위 바깥에 있다. 혹은 배경지식의 부족함으로 더 준비해야 하는 부분이 된다.

 

CP를 준비하는 과정은 Web 페이지를 만들거나 app을 만드는 것과는 방향이 아주 다르다. 이런 개발 과정은 중간중간 확인과 수정이 필요하기도 하고, 기능 구현을 외부에 의존하기도 한다. 실제 개발을 하는 프로그래머에게 제일 많이 하는 조언중 한가지는 이미 만들어져 있는 것을 다시 개발하려고 하지 말라는 것이다. ( Don't invent wheel again) 즉, 이미 기존에 사용할 수 있는 것들을 최대한 활용해서 문제해결에만 집중하라는 것이다. CP에서도 문제 해결에 집중해야 하지만, CP는 제한된 시간안에서 할 수 있는 것만을 대상으로 한다. 그리고, 외부에서 빌려오는 기능은 대부분이 제한되어 있다. Python이나 Java의 확장성이 대부분의 CP에서는 제약 조건이 되고, 언어에서 기본으로 제공하는 라이브러리 기능이외 추가적인 확장 기능은 없다. 

 

시간제한이 없다면, 거의 대부분의 문제는 단순한 Brute Force 를 통해서 답을 구할 수 있다. 시간 제한이 있기 때문에 조금은 효율적인 알고리즘을 적용하는 것이다. Brute force, simple implementation은 CP에서는 중요하고 잘 훈련해야 하는 부분이다. 잘 생각해야 하는 것이 CP는 black box 테스트이다. 어떻게 구현되어 있는가는 제한 조건만 만족한다면 문제가 되지 않는다. 즉, 지금 문제 해결을 위해 필요한 명확한 알고리즘과 그 구현을 익숙하게 구현하는 것을 목표로 공부를 하는 것이다. 너무 많은 자료조사나 공부가 항상 도움이 되는 것은 아니다. 새로운 아이디어, 어렵지만 잘 만들어진 알고리즘이 일반적인 문제해결에는 도움이 될것이다. 하지만, CP에서는 간단하게 할 수 있다면, 간단하게 해결하는 것이 좋다. 확장성을 생각해서 더 범용적이고 잘 정리된 알고리즘을 준비하기 위해서 필요한 시간동안 다음 문제를 고민하는 편이 훨씬 도움이 되고, 문제가 생겼을때 더 빨리 잘못된 부분을 찾아낼 수 있다.

 

그렇지만 CP 준비 과정에서는 알고리즘이나 자료구조에 대해서 공부하는 과정을 배제 할 수는 없다. 그래서, 공부를 한다면 문제 해결에 필요한 수준으로 구현하기 위해 필요한 것까지를 목표로 해야 한다. 많은 알고리즘을 학문적으로 증명하기 위해서는 복잡한 수준의 수학과 논리가 필요하고 그런 부분은 그것을 전공으로 공부하는 대학원에서나 필요한 일이다. CP에서 필요한 수준은 명확한 단계별 논리 흐름과 그때에 어떤 형태로 자료를 다루는가 하는 것이다. 끼워야 할 자리에 레고 모양이 맞으면 끼우면 된다. 레고공장에서 어떻게 블럭이 만들어지는지 알 필요는 없는 것이다.

 

동시에 이렇게 공부를 할 때 주의해야 할 부분도 있다. 즉, 알고리즘에 대한 메타인지와 함께 실제 알고리즘 구현에 대한 메타인지도 필요하다. 즉, I know vs I think I know 를 구분하는 것도 필요하지만, I can implement vs I think I can implement 도 구분히야 한다. 알고리즘이나 자료구조를 알고 있다고 실제로 구현하지 못하면 문제를 풀 수 없다. CP에 대한 훈련은 알고리즘에 대한 지식을 쌓는 것이 아니라, 알고리즘을 구현할 수 있는 능력을 훈련한다고 생각해야 한다.

 

남이 작성한 코드를 읽는 것은 도움이 되지만, 남의 코드를 단순히 외우는 것은 크게 도움이 되지 않는다. 프로그램은 외국어를 배워서 의사소통하는것과 결이 같다. 외국어가 부족해도 손짓이나 표정을 섞어서 의사소통을 할 수 있는 것은 실제로 같은 방법으로 의사소통의 경험이 있어야 가능하고, 동시에 같은 대상에 대해서 논의 할때 가능한 것이다. 또, 다른 사람의 프로그램 코드는 읽는 것을 목표로 해야 하지, 내용을 그냥 옮겨서 문제를 풀었다고 읽은 것이 아니다. 프로그램의 논리구조를 자기의 언어로 설명하는 것을 코드를 읽었다고 해야 한다. 다른 사람의 코드를 읽어서, 자기가 pseudo code로 프로그램을 작성할 수 있어야 코드를 읽고 이해했다고 할 수 있다. 

 

CP에서는 빠른 실패가 도움이 될 수도 있다. 경우에 따라 다르겠지만, 자기가 작성할때 생각하지 못했던 부분을 채점 프로그램이 찾아 줄 수도 있다. 생각하지 못한 입력의 범위나 출력의 범위를 알기 위해서는 빨리 실패하는 것도 좋다. 제출과 채점에 불이익이 없다면, 채점 시스템도 디버깅 툴로 이용할 수 있다. 훈련을 위해서 online judge 프로그램을 사용한다면, 당연히 활용할 수 있는 장점중의 하나이다.

 

2019년 미국 대표중 한명이었던 William Lin 이 CP 에 대해서 설명한 내용은 살펴볼 필요가 있다. ( link )  

 

CP를 훈련하고, USACO를 준비할때 참고하기 위한 리스트이다.  

  1. I/O에 주의한다. 항상 특정한 입력과 출력을 할 수 있도록 준비해야 한다. 
  2. 문제풀이는 종이에서도 충분히 가능하고 동시에 자기가 생각한 알고리즘의 소요시간이나 메모리에 대해서 분명히 이해하고 적용해야 한다.  
  3. 하나의 문제에 일정 시간 이상 사용하지 않는다.  한문제에 1시간이 넘어간다면, 지금 풀 수 없는 문제로 표시하고 다른 문제를 보거나, 다른 사람의 답안을 읽어보는 것도 좋다.
  4. 내 프로그램은 내가 검토하지 말자. online judge에서 검증 받을 수 있는 문제들로 연습해서, 시스템의 도움을 받자.
  5. 대부분은 현재 내 수준에 합당한 문제들로 연습하지만, 쉬운 문제, 어려운 문제들에도 일정 부분을 배정하자.
  6. 한번 풀었던 문제도 입력의 조건이나 출력의 조건이 달라지면 다른 문제가 된다. 문제를 풀고, 확장 가능성을 생각해보자.

 

'Basic Preparation' 카테고리의 다른 글

USAMO vs USACO III  (0) 2020.04.16
USAMO vs USACO II  (0) 2020.04.09
USACO vs USAMO I  (0) 2020.04.05
Teach Yourself C++  (0) 2019.09.17
C++ 공부 - 2019. 8월  (0) 2019.09.02

미국에서 USAMO 준비는 다음 책들이 일종의 교과서처럼 사용된다.

 

For AMC10/AMC12 

Introduction-level

- Prealgebra
- Introduction to Algebra
- Introduction to Geometry
- Introduction to Number Theory
- Introduction to Counting & Probability

Intermediate-level 
- Intermediate Algebra
- Intermediate Counting & Probability

 

Intermediate 시리즈는 제외하고 Problem Solving V1 을 보는 경우도 많다.

 

For AIME

the Art of Problem Solving Volume 1: the Basics
the Art of Problem Solving Volume 2: and Beyond

 

For USAMO or higher

How to Solve It: A New Aspect of Mathematical Method by G. Polya (Author)   
The Art and Craft of Problem Solving by Paul Zeitz (Author) 
How to Solve It: Modern Heuristics by Zbigniew Michalewicz (Author), David B. Fogel  (Author) 
Problem-Solving Strategies by Arthur Engel  (Author) 

 

영역별 이론 참고 도서들 

102 Combinatorial Problems by Titu Andreescu  (Author), Zuming Feng  (Author)
103 Trigonometry Problems: From the Training of the USA IMO Team by Titu Andreescu  (Author), Zuming Feng  (Author)
104 Number Theory Problems: From the Training of the USA IMO Team by Titu Andreescu  (Author), Dorin Andrica  (Author, Contributor), Zuming Feng  (Author)  
105 Algebra Problems from the AwesomeMath Summer Program by Titu Andreescu 
106 Geometry Problems from the AwesomeMath Summer Program by Titu Andreescu  (Author), Michal Rolinek  (Author), Josef Tkadlec  (Author)

여기에 소개된 책들이외에도 많은 국제대회, 국가대회들의 문제들과 표준 답안들이 있으므로, 그런 문제들을 이용해서 공부를 하게된다. AoPS ( link ), AwesomeMath ( link)를 찾아보면 더 많은 정보들을 얻을 수 있다.

 

앞쪽에 나와있는 AoPS에서 나온 책들은 단원별로 간단한 이론 설명이 있고, 해당하는 문제들이 있다. 대부분의 문제는 이론의 이해수준을 평가하기 위한 문제들이고, 과거 competition에 나왔던 문제들이나, 변형 문제돌이다.  AoPS 의 온라인 수업도 있고, 이런 교재들이 이용해서 설명하는 After school 프로그램들도 있다. 

 

조기교육 혹은 선행학습이라는 형태로 요즘은 아주 빠른 나이에 준비를 시작해서, 학교에서 진행하는 수학과는 별개로 준비를 하는 경우가 많다. 빠른 경우는 초등학교 저학년부터 시작하기도 하지만, 보통은 5~6학년에 시작해서 9~10학년쯤 마무리하는 경우가 보통이다. 대략 소요시간은 introduction series - 1년6개월~2년, AIME-1년, 그 다음 단계는 할 수 있는 만큼이라고들 한다.  여기서 말하는 AIME 전까지의 기본적인 과정만 잘 끝내도 일반적인 고등학교 2학년 수준까지 마무리하기 때문에 많이 참가하는 지도 모른다. 대회 성적이 만족스럽지 않아도, 일반적인 수학 선행학습으로 생각하고 몇년간 진행하는 것이다.

 

시험을 위해서 준비하는 훈련의 난이도는 자기가 준비하는 한단계 앞정도까지만을 권장한다. 어려운 난이도의 문제들은 일정 수준의 이론배경이 없으면 답안을 읽고 이해하기도 힘들기 때문에, 충분한 이론 학습이 되기 전에는 진행이 불가능하다. 그러므로, 다른 여러가지 공부와 마찬가지로 자기의 현재 수준에 대한 정확한 인지가 필요하고, 자기의 수준에 맞는 문제들이나 그것보다 조금 어려운 내용을 가지고 지속적으로 훈련하도록 한다. 

 

혹시, 어려운 난이도의 문제가 궁금한 사람들을 위해서, 2018년 short list problem (link) 를 적는다. 이 문제들은 2018년 imo 대회를 위해서 참가국들에서 제출한 문제들을 모아둔 것이고, 다음해 imo 대회에서 공개된다.  관련된 자료로는 INFINITY (link) 가 있다.

 

5~6학년에 시작해서 일주일에 10시간정도의 시간을 지속적으로 투여할때 10학년 혹은 11학년에는 달성할 수 있는 정도가 관심이 있는 사람이 훈련으로 가능한 수준의 한계라고 생각한다. 그리고, 그 수준은 AIME qualified가 될것이다. 누구에게나 시간이라는 자원은 항상 부족한 것이고, 수학공부에서 요구하는 몰입 수준을 생각한다면, 적어도 4~5년동안 거의 매일 한시간 이상의 시간을 투여한다는 것은 누구에게나 가능은 하지만 누구나 할 수는 없는 일이다. 지속과 몰입을 양립시키면서, 긴 시간동안 학습을 계속 할 수 있다면, 그 과정 자체가 훌륭한 성취라고 믿는다.

 

충분한 몰입과 훈련이 있다면, 학교 교과과정에 있는 수학이론들은 충분히 빠른 시간에 살펴볼 수 있는 것은 사실이다. 자기 주도학습으로 속도를 빨리해서 일반적인 수학이론을 쌓는 방법으로 일반 교과과정을 마무리 한다면 좋은 방향이라고 생각한다. 하지만, 학원이나 개인 교습의 형태로 교재 학습 속도만을 빨리하고 일반적인 문제 풀이를 반복하는 방법으로 진행하는 것은 시험을 잘 보기 위해서 준비하는 방법이지, 생각하는 방법을 훈련하는 것과는 거리가 있다.

 

수학적인 감각이나 문제풀이 방법은 꼭 어려운 수학문제를 푸는 것으로만 가능한 것은 아니다. 생각하는 방법이기 때문에 쉽고 단순한 문제들도 그 문제를 충분히 이해했다면, 그 문제를 약간 확장하거나 다른 풀이 방법을 찾아 보는 것으로도 전혀 다른 방향으로 진행될 수 있다. 피타고라스 정리를 확장했을 때가 궁금해서 적었던 메모가, Fermat's Last Theorem이 된것은 너무 유명한 것인지도 모른다.  

 

개인적으로 거의 10년 이상 올림피아드의 경향이나 문제들에 대해서 살펴보지 않았기 때문에, 이 자료의 정확도에 대해서 확신하기는 힘들지만, 최근에 찾아본 자료들에서 나오는 얘기도 아주 달라지지는 않은 것 같다. 다만, USAMO 나 그 이상의 수준의 문제들에 적용되는 이론들이 과거보다 많이 심화되고 어려워진것은 확실하다.

 

공부의 방법은 여러가지가 있겠지만, 여기서 논의하는 것은 USAMO라는 대회에 초점을 맞추고 설명한다. 어떤 시험을 준비하기 위해서 제일 기초적이고 중요한 부분은 과거에 출제된 문제들에 대한 분석이다. 필요한 이론 공부는 당연한 준비과정의 일부가 되야한다. 이런 기본적인 내용은 제외하고, 몇가지를 정리해본다.

 

1. Validation of every step 

2. If you can't solve a problem now, you need to check a problem type.

   - Lack of knowledge or Don't get the main idea of a problem

3. Recognize current level

   - I know vs I think I know

4. If you feel burn-out, take enough rest. 

5. Time scheduling

  - If you can assign an hour per each day, only plan for 40 minutes not an hour and a half.

6. If you skip a certain topic, you should remember the gap to fill.  

7. Don't hold a hard problem longer than a certain amount of time.

  - the expected time (problem # / test period) * N, ex) 5 min -> not exceed 20 min, N = 3

 

Time assign

  • Learning Theory : 1
  • Problem Solving : 2
  • Review Problem solving : 2
  • Learning Other's idea : 1
  • Review other's idea : 2 
    • analyze the tackling idea: agreeable, new, need to understand
    • Point to extend or another way to tackle

 

 

'Basic Preparation' 카테고리의 다른 글

USAMO vs USACO IV  (0) 2020.04.19
USAMO vs USACO II  (0) 2020.04.09
USACO vs USAMO I  (0) 2020.04.05
Teach Yourself C++  (0) 2019.09.17
C++ 공부 - 2019. 8월  (0) 2019.09.02

비슷한 두가지 시험에 참가하는 참가자들의 수가 많은 차이를 보이는지 생각해보기 위해서, 비슷한 점과 다른 점들을 살펴보겠다. 

 

먼저 두가지 시험을 준비하기 위해서는 자기주도 학습이 필요하다. 많은 영역들이 정규교과과정에서 다뤄지지 않거나, 약간의 언급만을 하기 때문에 실제적인 내용을 공부하기 위해서는 관련된 책을 기초로 공부해가는 과정이 필수적으로 요구된다. 물론, 학교외의 기관에서 제공하는 수업을 통해서 이런 과정을 준비할 수도 있지만, 모두에게 가능한 선택지가 아니므로 준비하는 개인의 자기주도 학습을 먼저 언급한다.  

 

자기주도 학습의 중요성과 함께 peer review도 중요한 부분을 차지한다. 올림피아드에 관심이 있어서 과거 기록들을 살펴보면 특정 그룹의 학생들이 지속적으로 상위권에 등장하는 것을 알 수 있다. 이것은 재능이 있는 사람들이 그 그룹에 모였기 때문에 나타난 현상이라는 설명은 쉽게 이해할 수 있다. 거기에 더해서 peer들과 상호작용의 영향도 이런 현상을 만든 동인중 하나로 생각해야 한다. 주변 peer들과의 경쟁에서 지속적인 자극을 받는것과  문제 해결 과정에서 fast feedback 을 주변 peer들에서 받는 것이 다른 한 부분이 된다. 수학의 증명이나 작성한 코드의 디버깅을 하는 경우, 자기의 논리를 자기가 검증하기 위해서는 먼저 자기 논리에서 충분한 거리만큼 빠져나와서 타인의 시선으로 분석을 할 수 있어야 더 쉽게 가능하다. 사람들은 자기가 원래 가지고 있던 논리의 편향성에서 자유롭지 못하고, 그래서 자기 논리의 문제점을 쉽게 발견하기는 어렵다. 글쓰기를 하는 경우에도, 작성한 글을 적어도 하루이상 지난뒤에 다시 살펴보라고 하는 것과 맥락을 같이 한다고 할 수 있다. 하지만, 주변에 비슷한 peer가 있는 경우는 자기의 논리나 프로그램을 타인의 시선에서 분석한 feedback 을 받을 수 있다.

 

또, 많은 다른 과목의 학습과 마찬가지로 이 두가지 영역에서는 analytical reasoning - 논리적 추론 과정이 아주 강조된다.  본질적으로 USACO, USAMO 모두 제한된 영역에서 논리적인 추론을 통한 문제해결이다. 다만, 그 문제 해결과정에서 수학적인 전개를 이용하느냐, 실제 동작하는 프로그램의 실행결과를 이용하는냐의 차이가 있을 뿐이다. 논리적 문제해결이 두가지에서 필요한 기본(Basic, not base)에 해당하는 영역이다. 여기에서 analytical reasoning을 언급하는 이유는 단기간에 발전할 수 없는 영역이기 때문이다. 특정한 방법을 암기하고 다시 그대로 재현하는 방법은 일반적인 시험준비에서 훌륭한 대비전략이다. 한데, 올림피아드라는 영역에서는 특정한 방법을 암기하고 재현해는 방법으로 준비하기는 암기해야 할 대상이 너무 많다. 암기할 수 있는 한계내에서 암기하고, 그것들을 어떤 방법으로 재현하고 연결하는가를 결정하는 과정이 이런 추론과정이고, 이것은 프로 바둑 기사들이 기보의 패턴을 인식하고 무의식적으로 복기하는 위해서 훈련하는 것처럼 상당한 기간동안의 훈련이 필요한 일이다. 즉, USAMO, USACO 모두 상당히 긴 시간동안 결과를 확신할 수 없는 상태에서 준비해야 하는 일이다.

 

두가지에서 서로 다른 부분들을 살펴보겠다. 

 

먼저, USAMO 의 과정은 다음과 같은 특징들에서 스케이트 보드나 스노보드의 half-pipe 와 비슷하다고 생각한다.  

  • 지속적인 가속과 적절한 방향 선택을 하지 못하면, 특정한 위치까지 올라갈 수 없다. 
  • 어떤 위치로 가는 경로가 알려져 있지만, 모르는 사람은 존재하는 경로를 읽을 수 없다.
  • 문제 풀이의 과정을 잘 이해하고 숙달하지 못하면, 비슷한 문제에 같은 방법을 적용할 수 없다.

또, USACO 와 다른 몇가지 부분도 있다. 

  • 문제의 영역이 잘 드러난다. ex) number theory, geometry, combinatorics, algebra
  • 풀이 과정의 전체 과정에서 명확한 논리 전개를 확인하는 white box test이다.
  • 문제 영역의 제한이 있지만, 훨씬 넓은 범위이다. (link)
    • 다른 곳에 출제된적이 없는 문제
    • 가능한 대학 수학 이전의 영역들

다음으로 USACO의 과정은 orienteering 과 비슷하다. 

  • 입력을 받아서 기대되는 출력을 만들어 내면 된다.
  • 마라톤처럼 정해진 경로로만 가야 하는 것이 아니라 지름길을 찾아서 이용하기를 권장한다.  
  • 입력이 바뀌면 전에 있던 경로가 유효하지 않을 수 있다. ( 숲에서 길 찾는 방법을 평원에서 적용하기는 힘들다.)
    • 특정 입력에서만 유용한 경로도 존재할 수 있다.  

또한 USAMO 와는 이런 다른 점이 있다.  

  • 구체적인 풀이 과정을 확인하지 않는 black box test 이다. 많은 경우 입력과 출력을 시스템에서 확인하고 평가한다.
  • 특정한 알고리즘, 수학적 이론이 구체적으로 제시된다. (link)
  • 알고리즘의 이론적인 이해가 부족해도, 알고리즘을 정확히 구현할수 있다면 문제 풀이에 사용할 수 있다. 

이렇게 두가지 시험에 대해서 비슷한 부분과 다른 부분들에 대해 정리해봤다. 이 내용들은 지극히 개인적인 조사와 분석에 의한 것이므로 실제와 다를 수 있다.  다음에는 이 분석을 기초로 어떻게 준비해야 효과적인 수 있을지에 대한 학습전략을 생각해 보겠다.

'Basic Preparation' 카테고리의 다른 글

USAMO vs USACO IV  (0) 2020.04.19
USAMO vs USACO III  (0) 2020.04.16
USACO vs USAMO I  (0) 2020.04.05
Teach Yourself C++  (0) 2019.09.17
C++ 공부 - 2019. 8월  (0) 2019.09.02

+ Recent posts