충남대학교 컴퓨터공학과 이영석 교수님의 "알고리즘" 강의 실습 내용입니다.

  • 실습 문제들의 코드 위주로 구성되어 있습니다.

문제 1: 피보나치 수열 구하기

#include <iostream>
 
using namespace std;
 
/**
 * 피보나치 수열을 재귀적으로 구하기 위한 함수
 */
int pib(int nInput) {
	if(nInput == 0) { // 0번째 값에 대한 종료조건
		return 0;
	} else if(nInput < 3) { // 1번째, 2번째 값에 대한 종료조건
		return 1;
	} else {
		return pib(nInput - 1) + pib(nInput - 2); // n - 1, n - 2번째에 대한 결과를 재귀적으로 구하여 더함
	}
}
 
int main() {
	int nInput;
	cin >> nInput;
	cout << pib(nInput) << endl;
}

문제 2: 유클리드 호제법을 이용한 최대공약수 구하기

#include <iostream>
 
using namespace std;
 
/**
 * 유클리드 호제법을 이용해 최대공약수를 재귀적으로 구하기 위한 함수
 */
int solve(int nI, int nJ) {
	int nRemain = nI % nJ;
	if(nRemain == 0) { // 나머지가 0일 경우에 제수를 반환
		return nJ;
	} else {
		return solve(nJ, nRemain); // 그렇지 않은 경우에 제수와 나머지를 재귀적으로 호제법을 적용함
	}
}
 
int main() {
	int nI, nJ;
	cin >> nI >> nJ;
	cout << solve(nI, nJ) << endl;
}

문제 3: 피라미드의 무게 구하기

#include <iostream>
#include <vector>
 
using namespace std;
 
long unsigned int nEnd; // 피라미드의 층수를 저장할 global 변수
 
/**
 * 벡터의 원소 합을 구하는 함수
 */
long unsigned int sum(vector<long unsigned int> vecInput) {
	long unsigned int nRes = 0;
	for(long unsigned int i = 0; i < vecInput.size(); i++) {
		nRes += vecInput[i]; // 벡터에서 값을 하나씩 꺼내 축적해줌
	}
	return nRes;
}
 
/**
 * 피라미드의 무게를 재귀적으로 구하기 위한 함수
 */
long unsigned int pyramid(vector<long unsigned int> vecInput, long unsigned int nAcc, long unsigned int nPhase) {
	if(nPhase == nEnd) { // 주어진 층수에 도달하면 지금까지 구한 무게를 반환
		return nAcc;
	} else {
		vector<long unsigned int> vecNext; // 현재 층의 원소들을 저장할 벡터
		vecNext.push_back(1); // 벡터에 1을 넣어줌
		for(long unsigned int i = 0; i < vecInput.size() - 1; i++) {
			vecNext.push_back(vecInput[i] + vecInput[i + 1]); // 해당 원소 바로 윗층에 있는 두 원소의 값을 더하여 현재 층의 원소 값을 구해냄
		}
		vecNext.push_back(1); // 벡터에 1을 넣어서 현재 층을 마무리함
		// 현재 층을 다음 층으로 전달하고 현재 층의 무게를 지금까지 구한 무게에 더해주며 층을 한단계 올려줌
		return pyramid(vecNext, nAcc + sum(vecNext), nPhase + 1);
	}
}
 
int main() {
	cin >> nEnd;
	vector<long unsigned int> vecInit;
	vecInit.push_back(1); // 피라미드의 맨 꼭대기에는 1밖에 없으므로 1을 넣어준 뒤
	cout << pyramid(vecInit, 1, 1) << endl; // 다음 층부터 연산하도록 지시
	return 0;
}

문제 4: 계단오르기

#include <iostream>
 
using namespace std;
 
/**
 * 계단의 갯수인 nN과 한번에 올라갈 수 있는 양인 nM을 인자로 줘 경우의 수를 세도록 함
 */
int solve(int nN, int nM) {
	if(nM <= 1) {
		return 1; // 계단의 갯수가 1보다 같거나 작으면 한번에 올라 갈 수 있음
	} else if(nM > nN) {
		return solve(nN, nN); // 한번에 올라갈 수 있는 계단의 최대가 계단의 수보다 크면 최대 계단의 수만큼 올라갈 수 있는것이나 마찬가지
	} else {
		int nRes = 0; // 한번에 올라갈 수 있는 계단의 수가 1일때부터 순차적으로 계산해 그 결과를 축적하기 위한 변수
		for(int i = 1; i <= nM; i++) {
			// 1 <= i <= nM인 i에 대해 먼저 i개의 계단을 올라간 뒤 남은 계단만큼을 한번에 최대 nM개 올라갈 수 있는 상태로 경우의 수를 재귀적으로 구함
			// i개의 계단을 먼저 올라가면 남은 계단은 nN - i개 일 것이고 한번에 올라갈 수 있는 계단의 최대 갯수는 여전히 nM이므로 이때의 경우의 수를 구함
			nRes += solve(nN - i, nM);
		}
		return nRes;
	}
}
 
int main() {
	int nN, nM;
	cin >> nN >> nM;
	cout << solve(nN, nM) << endl;
}