세준이는 컵 3개를 탁자 위에 일렬로 놓았다. 컵의 번호는 가장 왼쪽 컵부터 순서대로 1번, 2번, 3번 이고, 세준이는 이 컵을 이용해서 게임을 하려고 한다.
먼저 1번컵의 아래에 공을 하나 넣는다. 세준이는 두 컵을 고른 다음, 그 위치를 바꾸려고 한다. 예를 들어, 고른 컵이 1번과 2번이라면, 1번 컵이 있던 위치에 2번 컵을 이동시키고, 동시에 2번 컵이 있던 위치에 1번 컵을 이동시켜야 한다. 위치를 바꿀 때, 컵을 먼저 들고 이동해야 한다. 따라서, 공의 위치는 가장 처음 1번컵이 있던 위치와 같다.
세준이는 컵의 위치를 총 M번 바꿀 것이며, 컵의 위치를 바꾼 방법이 입력으로 주어진다. 위치를 M번 바꾼 이후에 공이 들어있는 컵의 번호를 구하는 프로그램을 작성하시오.
입력:
첫째 줄에 컵의 위치를 바꾼 횟수 M이 주어지며, M은 50보다 작거나 같은 자연수이다. 둘째 줄부터 M개의 줄에는 컵의 위치를 바꾼 방법 X와 Y가 주어지며, X번 컵과 Y번 컵의 위치를 서로 바꾸는 것을 의미한다.
컵을 이동시키는 중에 공이 컵에서 빠져나오는 경우는 없다. X와 Y의 값은 3보다 작거나 같고, X와 Y가 같을 수도 있다.
출력:
첫째 줄에 공이 들어있는 컵의 번호를 출력한다. 공이 사라져서 컵 밑에 없는 경우에는 -1을 출력한다.
풀이 방법:
모든 컵의 이동을 기억할 필요없이 공이 들어 있는 컵의 번호만 기억해주면 된다. 처음 공의 위치를 항상 1이며 이후 컵의 위치를 바꾼 방법 중 공의 위치의 번호가 있다면 이를 바꿔 주기만 하면 된다.
이제 10 살이 된 헨리(Henry)는 수학에 소질이 있다. 수학선생님인 아메스(Ahmes)는 오늘 헨리에게 분수에 대해 가르쳐줬고, 헨리는 분수를 이리저리 계산해보는 것이 너무 재미있었다. 그러던 중에 헨리는 1 보다 작은 분수를 여러 개의 서로 다른 단위분수의 합으로 표현할 수 있다는 것을 알아내었다. 여기서 단위분수란 분자가 1 인 분수를 말한다. 헨리는 여러 개의 분수에 대해 이를 시도해봤고, 시도해본 분수들은 모두 서로 다른 단위분수의 합으로 표현할 수 있었다. 예를 들어, 은와 같이 두 개의 단위 분수의 합으로 나타낼 수 있다.
헨리는 이런 발견을 선생님인 아메스에게 자랑스럽게 이야기했다. 아메스는 이를 듣고는 크게 기뻐하며 어린 제자를 칭찬했고, 이와 같이 하나의 분수를 서로 다른 단위분수의 합으로 표현한 것을 헨리식 표현법(Henry representation)이라고 이름 지었다. 즉, 분수의 헨리식 표현법은 총합이와 같게 되는 서로 다른 단위분수의 나열이다. 헨리와 아메스는 헨리식 표현법에 대하여 더욱 연구하였고, 마침내 모든 1 보다 작은 분수는 헨리식 표현법이 가능함을 증명하였다. 또한 헨리식 표현법이 유일하지 않다는 것도 알 수 있었다. 예를 들면,와 같이 여러 가지 다른 헨리식 표현법이 존재할 수 있다. 단, 정의에 의해, 헨리식 표현법에는 같은 단위분수가 두 개 이상 포함될 수 없으므로는 헨리식 표현법이 아님을 유념해야 한다.
아메스와 헨리는 또한 주어진 분수의 헨리식 표현법을 구하는 간단한 방법도 고안해냈다.인 양의 정수와로 이루어진 분수가 주어질 때에, 먼저를 만족하는 가장 큰 단위 분수를 계산한다. 그런 다음에서를 뺀 나머지에 대하여 위의 과정을 반복한다. 즉,를 만족하는 가장 큰 단위분수를 계산하고 뺀다. 이러한 과정을 나머지가 남지 않을 때까지 반복한다. 그러면 서로 다른 단위분수들을 순서대로 얻게 되며 그들의 합은 정확히와 같아진다. 아메스와 헨리는 이 알고리즘이 항상 종료하며 합이가 되는 서로 다른 단위분수들, 즉 헨리식 표현법을 출력함을 증명하였다.
아메스와 헨리는 당신에게 그들의 알고리즘을 컴퓨터 프로그램으로 구현해줄 것을 부탁했다. 입력으로 주어지는 1 보다 작은 분수를 아메스와 헨리의 알고리즘을 수행하여 헨리식 표현법을 계산할 때에 마지막 단위 분수의 분모를 출력하는 프로그램을 작성하시오. 예를 들어.라면, 아메스와 헨리의 알고리즘은을 출력하게 되므로 당신의 프로그램은 반드시 70 을 출력해야 한다.
입력:
입력 데이터는 표준입력을 사용한다. 입력은 T 개의 테스트 데이터로 구성된다. 입력의 첫 번째 줄에는 테스트 데이터의 개수 T 가 정수로 주어진다. 각 테스트 데이터는 한 줄로 구성되며, 여기에는 입력 분수
를 의미하는 두 개의 정수와(1 ≤ < ≤ 10,000) 가 주어진다. 이때,와는 서로소이며, 입력분수에 대해 아메스와 헨리의 알고리즘을 실행했을 때에 출력되는 단위 분수가 순서대로라면,의 부등식을 만족한다고 가정할 수 있다.
출력:
출력은 표준출력을 사용한다. 각 테스트 데이터에 대해, 정확히 한 줄을 출력해야 하며 여기에는 정수 하나만을 출력한다. 이 정수는 아메스와 헨리의 알고리즘을 입력 분수 에 대해 실행했을 때, 출력되는 헨리식 표현법의 마지막 단위분수의 분모와 같아야 한다.
풀이 방법:
가장 큰 1/x를 구하기 위해서는 원래 분수에서 분자를 1로 만들었을 때에 생기는 분모의 값을 올림해주면 된다. (분수의 경우에 분모가 작을수록 크다.)
따라서 (a/b-1/x1-1/x2- .... )의 분자가 1이 될 때까지 while로 반복하도록 한다. 또한 새 분수를 만들고 나서 약분하는 작업이 필요하므로 분수 계산을 도와주는 모듈인 fraction을 사용하도록 한다.
각 테스트 케이스는 한 줄로 이루어져 있으며, 2^31 -1 을 넘지 않는 두 자연수 n (n>=1) 과 k(0<=k<=n)로 이루어져 있다.
입력의 마지막 줄에는 0이 두 개 주어진다.
출력:
각 테스트 케이스에 대해서, 정답을 출력한다. 항상 정답이 2^31보다 작은 경우만 입력으로 주어진다.
풀이 방법:
일반적으로 nCk 를 구하는 문제와 동일하긴 하지만 n과 k의 크기가 많이 크므로 이를 정제하는 작업이 필요하다. 이전 문제에서 nCk를 구할 때 n!/k!*(n-k)!을 통해서 값을 얻는다고 하지만 실제로 사람이 계산할 때는 그렇게 하지 않는다. 10C4가 있다면 10!/4!6!을 통해서 계산을 해야겠지만 사람이라면 약분을 해서 10*9*8*7/4! 으로 구하게 된다. 따라서 이 문제도 약분을 통해서 간략화해야 한다. 또한 nCk=nCn-k와 동일하다는 공식도 존재하므로 k가 일정 값을 넘어가면 이를 통해서 k의 크기를 줄이도록 했다.
R x S와 같은 형식으로 사용하며 카디날리티가 i인 릴레이션 R(A1, A2,... , An)과 카디날리티가 j인 릴레이션 S(B1, B2,...., Bm)의 카티션 곱 R x S는 차수가 n+m이고, 카디날리티가 i*j이고, 애트리뷰트가 (A1, A2, ..., An, B1, B1, ..., Bm)이며 R과 S의 투플들의 모든 가능한 조합인 릴레이션, 카티션 곱의 결과 릴레이션은 크기가 매우 클 수 있다. 또한 사용자가 원하는 값은 카티션 곱의 일부분인 경우가 대다수이므로 유용한 연산자는 아니다.
관계 대수의 완전성
실렉션, 프로젝션, 합집합, 차집합, 카티션 곱은 관계 대수의 필수적인 연산자이다. 다른 관계 연산자들은 필수적인 관계 연산자를 두 개 이상 조합하여 표현 할 수 있다.
임의의 질의어가 필수적인 관계 대수 연산자들만큼의 표현력을 갖고 있으면 관계적으로 완전하다고 말한다.
조인 연산자
두 개의 릴레이션으로부터 연관된 투플들을 결합하는 연산자이다. 관계 데이터베이스에서 두 개 이상의 릴레이션들의 관계를 다루는데 매우 중요한 연산자이다.
세타 조인 - 두 릴레이션의 카티션 곱의 결과 중에서 조인 조건을 만족하는 투플들로 이루어진 릴레이션, 조인 조건은 =, <>, <=,<,>=,> 가 있다.
동등 조인 - 세타 조인의 조인 조건 중 = 인 조인
자연 조인 - 두 릴레이션의 공통된 애트리뷰트에 대해 동등 조인을 수행하고, 동등 조인의 결과 릴레이션에 있는 두 개의 조인 애트리뷰트 중 하나를 제외한 조인, 가장 자주 사용된다.
디비전 연산자
차수가 n+m인 릴레이션R 과 차수가 m인 릴레이션 S의 디비전 R / S는 차수가 n이고, S에 속하는 모든 투플 u에 대하여 투플 tu가 R에 존재하는 투플 t들의 집합 " 모든... 에 대해 ~하는" 형태의 질의에 사용될 수 있다.
기존에는 관계 대수는 집단함수와 그룹화를 제공하지 않았으나 지금은 제공을 하고 있다.
(ex, AVG, SUM, MIN, MAX, COUNT,...)
외부 조인
상대 릴레이션에서 대응되는 투플을 갖지 못하는 투플이나 조인 애트리뷰트에 널값이 들어 있는 투플들을 다루기 위해서 조인 연산을 확장한 조인이다. 두 릴레이션에서 대응되는 투플을 갖지 않는 투플과 조인 애트리뷰트에 널값을 갖는 투플도 결과에 포함시킨다. 왼쪽 외부 조인, 오른쪽 외부 조인, 완전 외부 조인이 있다.
자연수 N과 정수 K가 주어졌을 때 이항 계수 (N, K)를 10,007로 나눈 나머지를 구하는 프로그램을 작성하시오.
입력:
첫째 줄에 N과 K가 주어진다. (1<=N<=1,000, 0<=K<=N)
출력:
(N, K)를 10,007로 나눈 나머지를 출력한다.
풀이 방법:
N의 크기가 커짐에 따라서 더 이상 이항계수 문제를 재귀적방법으로 해결할 수 없다. 일반적으로 재귀함수가 가독성이 좋긴 하지만 동일한 함수를 자주 호출하다보니 N이 커질수록 stack overflow가 발생할 수 있다. 따라서 이를 해결하는 방법으로 dp (메모리제이션) 을 사용한다. 작은 값의 함수들 부터 배열에 값을 저장하면서 원하는 값까지 진행을 하는 방식이다.
따라서 이항계수1 문제와 풀이는 비슷하나 함수를 호출하는 것이 아닌 배열의 값을 호출한다는 차이가 있다.