[문제]
0보다 크거나 같은 정수 N이 주어진다. 이때, N!을 출력하는 프로그램을 작성하시오.
[입력]
첫쨰 줄에 정수 가 주어진다.
[출력]
첫째 줄에 N!을 출력한다.
예제 입력 1 예제 출력 1 10 3628800
예제 입력 2 예제 출력 2 0 1
고등학교 수학시간에 배운 을 구하는 것이다.
N! = N * (N-1) * (N-2) * . . . * 2 * 1
을 구하기 위해서 재귀함수를 이용할 수 있다.
팩토리얼을 구하기 위한 함수 순서는 다음과 같다.
1) n의 값을 팩토리얼 함수의 입력으로 받는다.
2) n의 값이 10이라면 1을 함수의 반환값으로 반환하고, 프로그램을 종료한다.
3) n-1의 값을 팩토리얼 함수에 전달하여 1)을 호출한다
4) 2)에서 얻은 결괏값과 n을 곱한 값을 함수의 반환값으로 반환한다.
순서 2)와 같이 이 1이라면 더 이상 자기 자신을 호출하지 않고 프로그램을 종료하는 시점을 적어준 것이 포인트이다.
factorial(5)는 코드라인 2에 의해 5는 1보다 크기 때문에 5 * factorial(4)가 실행되고,
factorial(4)는 코드라인 2에 의해 5는 1보다 크기 때문에 5 * factorial(3)가 실행되고,
factorial(3)는 코드라인 2에 의해 5는 1보다 크기 때문에 5 * factorial(2)가 실행되고,
factorial(2)는 코드라인 2에 의해 5는 1보다 크기 때문에 5 * factorial(1)가 실행되고,
factorial(1)은 코드라인 1에 의해 1 값을 반환한다.
factorial(1)은 1을 반환했으므로
factorial(2)는 2 * factorial(1)은 2가 되고
factorial(3)은 3 * factorial(2)는 6이 되고
factorial(4)은 3 * factorial(3)는 24이 되고
factorial(5)은 3 * factorial(4)는120이 된다.
[문제]
세 개의 장대가 있고 첫 번째 장대에는 반경이 서로 다른 n개의 원판이 쌓여 있다. 각 원판은 반경이 큰 순서대로 쌓여있다. 이제 수도승들이 다음 규칙에 따라 첫 번째 장대에서 세 번째 장대로 옮기려 한다.1. 한 번에 한 개의 원판만을 다른 탑으로 옮길 수 있다. 2. 쌓아 놓은 원판은 항상 위의 것이 아래의 것보다 작아야 한다.
이 작업을 수행하는데 필요한 이동 순서를 출력하는 프로그램을 작성하라. 단, 이동 횟수는 최소가 되어야 한다.
아래 그림은 원판이 5개인 경우의 예시이다.
[입력]
첫째 줄에 첫 번째 장대에 쌓인 원판의 개수 이 주어진다.
[출력]
첫째 줄에 옮긴 횟수 K를 출력한다.두 번째 줄부터 수행 과정을 출력한다. 두 번째 줄부터 K개의 줄에 걸쳐 두 정수 A B를 빈칸을 사이에 두고 출력하는데, 이는 A번째 탑의 가장 위에 있는 원판을 B번째 탑의 가장 위에 옮긴다는 뜻이다.
예제 입력 1 예제 출력 1 3 7 1 3 1 2 3 2 1 3 2 1 2 3 1 3
3개의 장대가 있고, 첫 번째 장대에는 서로 다른 n개의 원판이 쌓여있다.
- 한 번에 한 개의 원판만을 다른 탑으로 옮길 수 있다.
- 쌓아 놓은 원판은 항상 위의 것이 아래의 것보다 작아야 한다.
2가지 규칙을 지키며 첫 번째 장대에서 세 번째 장대로 원판을 전부 옮기면 되는 문제이다. 이때 원판이 이동하는 장대를 출력하자.
<예제 1>
2개의 원판을 첫 번째 장대에서 세 번째 장대로 옮기기 위해서
1) 원판 1은 첫 번째 장판에서 두 번째 장판으로 이동한다.
2) 원판 2는 첫 번째 장판에서 세 번째 장판으로 이동한다.
3) 원판 1은 두 번째 장판에서 세 번째 장판으로 이동한다.
<예제 2>
3개의 원판을 첫 번째 장대에서 세 번째 장대로 옮기기 위해서
1)
2)
3)
4)
5)
6)
7)
1) 가장 큰 원판 n은 맨 밑에 있어야 하므로 원판 n-1개를 첫 번째 장대에서 두 번째 장대로 옮긴다.
2) 원판 n을 첫 번째 장대에서 세 번째 장대로 옮긴다.
3) 원판 n-1개를 두 번째 장대에서 세 번째 장대로 옮긴다.
[문제]
유현이가 새 집으로 이사했다. 새 집의 크기는 N X N의 격자판으로 나타낼 수 있고, 1 X 1 크기의 정사각형 칸으로 나누어져 있다. 각각의 칸은 ()로 나타낼 수 있다. 여기서 은 행의 번호, 는 열의 번호이고, 행과 열의 번호는 1부터 시작한다. 각각의 칸은 빈칸이거나 벽이다.오늘은 집 수리를 위해서 파이프 하나를 옮기려고 한다. 파이프는 아래와 같은 형태이고, 2개의 연속된 칸을 차지하는 크기이다.
파이프는 회전시킬 수 있으며, 아래와 같이 3가지 방향이 가능하다.
파이프는 매우 무겁기 떄문에, 유현이는 파이프를 밀어서 이동시키려고 한다. 벽에는 새로운 벽지를 발랐기 때문에, 파이프가 벽을 긁으면 안 된다. 즉, 파이프는 항상 빈칸만 차지해야 한다.
파이프를 밀 수 있는 방향은 총 3가지가 있으며, →, ↘, ↓ 방향이다. 파이프는 밀면서 회전시킬 수 있다. 회전은 45도만 회전시킬 수 있으며, 미는 방향은 오른쪽, 아래, 또는 오른쪽 아래 대각선 방향이어야 한다.
파이프가 가로로 놓여진 경우에 가능한 이동 방법은 총 2가지, 세로로 놓여진 경우에는 2가지, 대각성 방향으로 놓여진 경우에는 3가지가 있다.
아래 그림은 파이프가 놓여진 방향에 따라서 이동할 수 있는 방법을 모두 나타낸 것이고, 꼭 빈칸이어야 하는 곳은 색으로 표시되어져 있다.
가장 처음에 파이프는 (1, 1)와 (1, 2)를 차지하고 있고, 방향은 가로이다. 파이프의 한쪽 끝을 (N, N)로 이동시키는 방법의 개수를 구해보자.
[입력]
첫째 줄에 집의 크기 이 주어진다. 둘쨰 줄부터 N개의 줄에는 집의 상태가 주어진다. 빈칸은 0, 벽은 1로 주어진다. (1, 1)과 (1, 2)는 항상 빈칸이다.
[출력]
첫째 줄에 파이프의 한쪽 끝을 (N, N)으로 이동시키는 방법의 수를 출력한다. 이동시킬 수 없는 경우에는 0을 출력한다. 방법의 수는 항상 1,000,000보다 작거나 같다.
예제 입력 1 예제 출력 1 3 1 0 0 0 0 0 0 0 0 0
예제 입력 2 예제 출력 2 4 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
예제 입력 3 예제 출력 3 5 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
예제 입력 4 예제 출력 4 6 13 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
가로와 세로의 길이가 n이고 0과 1로 이루어진 집의 상태가 입력으로 주어진다.
집의 상태가 0이면 파이프를 둘 수 있고, 1이면 파이프를 둘 수 없다.파이프는 아래와 같이 집의 칸 2개를 사용하여 둘 수 있고,
3가지 방향이 가능하다.
이때 파이프는7가지의 이동 방법이 있다.
(1, 1)(1, 2)위치에 있는 파이프의 한 쪽 끝을 (n, n) 좌표로 이동시키는 방법의 개수를 구하는 문제이다.
크게 3가지의 의미로 나눌 수 있다.
코드라인 1~12를 자세히 살펴보자.
[문제]
아래 <그림 1>과 같이 여러개의 정사각형칸들로 이루어진 정사각형 모양의 종이가 주어져 있고, 각 정사각형들은 하얀색으로 칠해져 있거나 파란색으로 칠해져 있다. 주어진 종이를 일정한 규칙에 따라 잘라서 다양한 크기를 가진 정사각형 모양의 하얀색 또는 파란색 색종이를 만들려고 한다.전체 종이의 크기가 N X N(, 는 1이상 7 이하의 자연수)이라면 종이를 자르는 규칙은 다음과 같다.
전체 종이가 모두 같은 색으로 칠해져 있지 않으면 가로와 세로로 중간 부분을 잘라서 <그림 2>의 Ⅰ, Ⅱ, Ⅲ, Ⅳ와 같이 똑같은 크기의 네 개의 N / 2 X N / 2 색종이로 나눈다. 나누어진 종이 Ⅰ, Ⅱ, Ⅲ, Ⅳ 각각에 대해서도 앞에서와 마찬가지로 모두 같은 색으로 칠해져 있지 않으면 같은 방법으로 똑같은 크기의 네 개의 색종이로 나눈다. 이와 같은 과정을 잘라진 종이가 모두 하얀색 또는 모두 파란색으로 칠해져 있거나, 하나의 정사각형 칸이 되어 더 이상 자를 수 없을 때까지 반복한다.
위와 같은 규칙에 따라 잘랐을 때 <그림 3>은 <그림 1>의 종이를 처음 나눈 후의 상태를, <그림 4>는 두 번째 나눈 후의 상태를, <그림 5>는 최종적으로 만들어진 다양한 크기의 9장의 하얀색 색종이와 7장의 파란색 색종이를 보여주고 있다.
입력으로 주어진 종이의 한 변의 길이 N과 각 정사각형칸의 색(하얀색 또는 파란색)이 주어질 때 잘라진 하얀색 색종이와 파란색 색종이의 개수를 구하는 프로그램을 작성하시오.
[입력]
첫째 줄에는 전체 종이의 한 변의 길이 N이 주어져 있다. N은 2, 4, 8, 16, 32, 64, 128 중 하나이다. 색종이의 각 가로줄의 정사각형칸들의 색이 윗줄부터 차례로 둘째 줄부터 마지막 줄까지 주어진다. 하얀색으로 칠해진 칸은 0, 파란색으로 칠해진 칸은 1로 주어지며, 각 숫자 사이에는 빈칸이 하나씩 있다.
[출력]
첫째 줄에는 잘라진 하얀색 색종이의 개수를 출력하고, 둘째 줄에는 파란색 색종이의 개수를 출력한다.
예제 입력 1 예제 출력 1 8 9 1 1 0 0 0 0 1 1 7 1 1 0 0 0 0 1 1 0 0 0 0 1 1 0 0 0 0 0 0 1 1 0 0 1 0 0 0 1 1 1 1 0 1 0 0 1 1 1 1 0 0 1 1 1 1 1 1 0 0 1 1 1 1 1 1
문제의 <그림 1>과 같이 1 또는 0으로 이루어진 정사각형이 주어진다. 1은 파란색 종이를 나타내고, 0은 하얀색 종이를 나타낸다.
종이의 길이가 이고 각 종이의 좌표를 (x, y)로 표시한다면
처음으로는
(0~n, 0~n) 구역이 모두 같은 색(모두 하얀색 또는 모두 파란색)인지 확인하여 모두 같은 색이라면 해당 색깔의 종이 수를 1 더하고 프로그램을 종료한다.
모두 같은 색이 아니라면(0~n/2, 0~n/2)
(n/2~n, 0~n/2)
(0~n/2, n/2~n)
(n/2~n, n/2~n)4구역으로 나눈 후 각 구역마다 모두 같은 색(모두 하얀색 또는 모두 파란색)이라면 그 색깔의 종이수를 1 더하고, 같은 색이 아니라면 해당 구역을 다시 한 번
(0~n/2, 0~n/2)
(n/2~n, 0~n/2)
(0~n/2, n/2~n)
(n/2~n. n/2~n)4구역으로 나눈다.
이런 식으로 계속 반복하여 총 하얀색 종이의 개수와 총 파란색 종이의 개수를 출력하면 되는 문제이다.
이 예제는 정말 분할정복의 정석적인 예제라고 할 수 있다.