728x90
반응형
SMALL

문제 설명

효진이는 멀리 뛰기를 연습하고 있습니다. 효진이는 한번에 1칸, 또는 2칸을 뛸 수 있습니다. 칸이 총 4개 있을 때, 효진이는

(1칸, 1칸, 1칸, 1칸)

(1칸, 2칸, 1칸)

(1칸, 1칸, 2칸)

(2칸, 1칸, 1칸)

(2칸, 2칸)

의 5가지 방법으로 맨 끝 칸에 도달할 수 있습니다. 멀리뛰기에 사용될 칸의 수 n이 주어질 때, 효진이가 끝에 도달하는 방법이 몇 가지인지 알아내, 여기에 1234567를 나눈 나머지를 리턴하는 함수, solution을 완성하세요. 예를 들어 4가 입력된다면, 5를 return하면 됩니다.

제한 사항

  • n은 1 이상, 2000 이하인 정수입니다.

입출력 예

n result

4 5
3 3

입출력 예 설명

입출력 예 #1

위에서 설명한 내용과 같습니다.

입출력 예 #2

(2칸, 1칸)

(1칸, 2칸)

(1칸, 1칸, 1칸)

총 3가지 방법으로 멀리 뛸 수 있습니다.

package LV2;

public class H12914 {
	public int solution(int n) {
		// waysToReach 배열은 각 위치에 도달할 수 있는 방법의 수를 저장합니다.
		int[] waysToReach = new int[n+1];

		// 0번째 위치와 1번째 위치에 도달하는 방법은 각각 1가지입니다.
		waysToReach[0] = 1;
		waysToReach[1] = 1;

		// 2번째 위치부터는 각 위치에 도달하는 방법의 수는 이전 두 위치에 도달하는 방법의 수의 합이 됩니다.
		for (int i = 2; i <= n; i++) {
			waysToReach[i] = (waysToReach[i-1] + waysToReach[i-2]) % 1234567;
		}

		// n번째 위치에 도달하는 방법의 수를 반환합니다.
		return waysToReach[n];
	}
}

효진이의 문제는 다이나믹 프로그래밍(Dynamic Programming) 문제의 한 형태로, 이 문제를 풀 때 사용하는 기본적인 아이디어는 각 단계에서 가능한 경로의 수를 계산하는 것이다. 한 칸 또는 두 칸을 뛰는 것이 가능하므로, n번째 칸에 도달하는 방법의 수는 n-1번째 칸과 n-2번째 칸에 도달하는 방법의 수의 합과 같다.

waysToReach

**waysToReach**는 일종의 동적 프로그래밍 테이블로 사용되는 배열이다. 이 배열의 각 인덱스는 거리(칸의 수)를 나타내며, 해당 인덱스에 저장된 값은 그 거리에 도달하는 방법의 수를 나타낸다.

예를 들어, **waysToReach[3]**는 효진이가 3칸을 건너뛸 수 있는 방법의 수를 저장하고 있다. 이 값은 효진이가 한 번에 한 칸 또는 두 칸을 뛸 수 있다는 사실을 바탕으로, waysToReach[2](2칸을 건너뛸 수 있는 방법의 수)와 waysToReach[1](1칸을 건너뛸 수 있는 방법의 수)의 합이 된다.

이런 식으로 waysToReach 배열은 효진이가 각 거리에 도달할 수 있는 방법의 수를 계산하고 저장하는 데 사용된다. 그래서 마지막에 **waysToReach[n]**을 반환함으로써, 효진이가 n칸을 건너뛸 수 있는 방법의 수를 알아낼 수 있다.

728x90
반응형
LIST

'알고리즘 > 프로그래머스 JAVA LV.2' 카테고리의 다른 글

점프와 순간 이동  (0) 2023.05.24
예상 대진표  (0) 2023.05.24
영어 끝말잇기  (0) 2023.05.23
N개의 최소공배수  (0) 2023.05.23
의상  (0) 2023.05.23
728x90
반응형
SMALL

문제 설명

1부터 n까지 번호가 붙어있는 n명의 사람이 영어 끝말잇기를 하고 있습니다. 영어 끝말잇기는 다음과 같은 규칙으로 진행됩니다.

  1. 1번부터 번호 순서대로 한 사람씩 차례대로 단어를 말합니다.
  2. 마지막 사람이 단어를 말한 다음에는 다시 1번부터 시작합니다.
  3. 앞사람이 말한 단어의 마지막 문자로 시작하는 단어를 말해야 합니다.
  4. 이전에 등장했던 단어는 사용할 수 없습니다.
  5. 한 글자인 단어는 인정되지 않습니다.

다음은 3명이 끝말잇기를 하는 상황을 나타냅니다.

tank → kick → know → wheel → land → dream → mother → robot → tank

위 끝말잇기는 다음과 같이 진행됩니다.

  • 1번 사람이 자신의 첫 번째 차례에 tank를 말합니다.
  • 2번 사람이 자신의 첫 번째 차례에 kick을 말합니다.
  • 3번 사람이 자신의 첫 번째 차례에 know를 말합니다.
  • 1번 사람이 자신의 두 번째 차례에 wheel을 말합니다.
  • (계속 진행)

끝말잇기를 계속 진행해 나가다 보면, 3번 사람이 자신의 세 번째 차례에 말한 tank 라는 단어는 이전에 등장했던 단어이므로 탈락하게 됩니다.

사람의 수 n과 사람들이 순서대로 말한 단어 words 가 매개변수로 주어질 때, 가장 먼저 탈락하는 사람의 번호와 그 사람이 자신의 몇 번째 차례에 탈락하는지를 구해서 return 하도록 solution 함수를 완성해주세요.

제한 사항

  • 끝말잇기에 참여하는 사람의 수 n은 2 이상 10 이하의 자연수입니다.
  • words는 끝말잇기에 사용한 단어들이 순서대로 들어있는 배열이며, 길이는 n 이상 100 이하입니다.
  • 단어의 길이는 2 이상 50 이하입니다.
  • 모든 단어는 알파벳 소문자로만 이루어져 있습니다.
  • 끝말잇기에 사용되는 단어의 뜻(의미)은 신경 쓰지 않으셔도 됩니다.
  • 정답은 [ 번호, 차례 ] 형태로 return 해주세요.
  • 만약 주어진 단어들로 탈락자가 생기지 않는다면, [0, 0]을 return 해주세요.

입출력 예

n words result

3 ["tank", "kick", "know", "wheel", "land", "dream", "mother", "robot", "tank"] [3,3]
5 ["hello", "observe", "effect", "take", "either", "recognize", "encourage", "ensure", "establish", "hang", "gather", "refer", "reference", "estimate", "executive"] [0,0]
2 ["hello", "one", "even", "never", "now", "world", "draw"] [1,3]

입출력 예 설명

입출력 예 #1

3명의 사람이 끝말잇기에 참여하고 있습니다.

  • 1번 사람 : tank, wheel, mother
  • 2번 사람 : kick, land, robot
  • 3번 사람 : know, dream, tank

와 같은 순서로 말을 하게 되며, 3번 사람이 자신의 세 번째 차례에 말한 tank라는 단어가 1번 사람이 자신의 첫 번째 차례에 말한 tank와 같으므로 3번 사람이 자신의 세 번째 차례로 말을 할 때 처음 탈락자가 나오게 됩니다.

입출력 예 #2

5명의 사람이 끝말잇기에 참여하고 있습니다.

  • 1번 사람 : hello, recognize, gather
  • 2번 사람 : observe, encourage, refer
  • 3번 사람 : effect, ensure, reference
  • 4번 사람 : take, establish, estimate
  • 5번 사람 : either, hang, executive

와 같은 순서로 말을 하게 되며, 이 경우는 주어진 단어로만으로는 탈락자가 발생하지 않습니다. 따라서 [0, 0]을 return하면 됩니다.

입출력 예 #3

2명의 사람이 끝말잇기에 참여하고 있습니다.

  • 1번 사람 : hello, even, now, draw
  • 2번 사람 : one, never, world

와 같은 순서로 말을 하게 되며, 1번 사람이 자신의 세 번째 차례에 'r'로 시작하는 단어 대신, n으로 시작하는 now를 말했기 때문에 이때 처음 탈락자가 나오게 됩니다.

package LV2;

import java.util.HashSet;
import java.util.Set;

public class H12981 {
	public int[] solution(int n, String[] words) {
		Set<String> wordSet = new HashSet<>();
		String lastWord = words[0];
		wordSet.add(lastWord);

		for (int i = 1; i < words.length; i++) {
			// 끝말잇기 규칙을 위반하거나 이미 사용된 단어를 사용한 경우
			if (lastWord.charAt(lastWord.length() - 1) != words[i].charAt(0) || !wordSet.add(words[i])) {
				return new int[]{(i % n) + 1, (i / n) + 1};
			}
			lastWord = words[i];
		}

		// 탈락자가 없는 경우
		return new int[]{0, 0};
	}
}

HashSet을 사용하여 이전에 사용된 단어를 추적하고, 각 단어의 마지막 문자와 다음 단어의 첫 문자를 비교

각 단어를 순회하면서 끝말잇기의 규칙을 준수하는지 확인한다. 끝말잇기의 규칙을 위반하거나 이미 사용된 단어를 사용한 경우, 그 사람의 번호와 차례를 반환한다. 만약 모든 단어가 끝말잇기 규칙을 준수하면 [0, 0]을 반환한다.

728x90
반응형
LIST

'알고리즘 > 프로그래머스 JAVA LV.2' 카테고리의 다른 글

예상 대진표  (0) 2023.05.24
멀리 뛰기  (0) 2023.05.24
N개의 최소공배수  (0) 2023.05.23
의상  (0) 2023.05.23
구명보트  (0) 2023.05.23
728x90
반응형
SMALL

문제 설명

두 수의 최소공배수(Least Common Multiple)란 입력된 두 수의 배수 중 공통이 되는 가장 작은 숫자를 의미합니다. 예를 들어 2와 7의 최소공배수는 14가 됩니다. 정의를 확장해서, n개의 수의 최소공배수는 n 개의 수들의 배수 중 공통이 되는 가장 작은 숫자가 됩니다. n개의 숫자를 담은 배열 arr이 입력되었을 때 이 수들의 최소공배수를 반환하는 함수, solution을 완성해 주세요.

제한 사항

  • arr은 길이 1이상, 15이하인 배열입니다.
  • arr의 원소는 100 이하인 자연수입니다.

입출력 예

arr result

[2,6,8,14] 168
[1,2,3] 6
package LV2;

public class H12953 {
	public static void main(String[] args) {
		// 테스트 케이스 정의
		int[] arr1 = {2, 6, 8, 14};
		int[] arr2 = {1, 2, 3};

		// 테스트 케이스 실행 및 결과 출력
		System.out.println(solution(arr1)); // 출력: 168
		System.out.println(solution(arr2)); // 출력: 6
	}

	// 최소공배수를 구하는 메서드
	public static int solution(int[] arr) {
		// 첫 번째 값을 answer로 초기화
		int answer = arr[0];

		// arr 배열의 각 요소에 대해
		for (int i = 1; i < arr.length; i++) {
			// answer와 다음 값의 최소공배수를 계산하여 answer 업데이트
			answer = lcm(answer, arr[i]);
		}

		// 최종 계산된 최소공배수 반환
		return answer;
	}

	// 최대공약수를 구하는 메서드
	private static int gcd(int a, int b) {
		// b가 0이 아닐 동안 반복
		while (b != 0) {
			// a를 b로 나눈 나머지를 r에 저장
			int r = a % b;
			// a에 b를 대입
			a = b;
			// b에 r을 대입
			b = r;
		}
		// 최대공약수인 a 반환
		return a;
	}

	// 최소공배수를 구하는 메서드
	private static int lcm(int a, int b) {
		// a와 b의 곱을 a와 b의 최대공약수로 나눈 값 반환
		return a * b / gcd(a, b);
	}
}

두 수 a와 b의 최소공배수 LCM(a, b)는 a * b / GCD(a, b)로 계산할 수 있다. 이 때, GCD(a, b)는 a와 b의 최대공약수를 의미한다. 따라서 최대공약수를 찾는 함수가 필요하며, 유클리드 호제법을 이용해 최대공약수를 구할 수 있다.

두 수 이상의 최소공배수는 첫 번째 수와 두 번째 수의 최소공배수를 구하고, 그 결과와 세 번째 수의 최소공배수를 구하는 방식으로 순차적으로 계산할 수 있다.

유클리드 호제법

유클리드 호제법은 두 자연수의 최대공약수를 구하는 알고리즘 중 하나이다. 이름에서 알 수 있듯이, 이 방법은 고대 그리스의 수학자 유클리드가 저술한 '원론'에서 처음 소개되었다.

유클리드 호제법은 다음과 같은 원리에 기반한다: 두 수 A와 B(A > B)의 최대공약수는 B와 A를 B로 나눈 나머지 R의 최대공약수와 같다. 이 원리를 이용해 나머지가 0이 될 때까지 반복하여 나누는 과정을 거친다.

다음은 유클리드 호제법을 통해 최대공약수를 찾는 절차이다:

  1. 두 수 A와 B가 있을 때, A가 B보다 크다고 가정한다.
  2. A를 B로 나눈 나머지를 R이라 한다.
  3. 이제 B를 새로운 A로, R을 새로운 B로 간주하고 다시 A를 B로 나눈다.
  4. 이 과정을 나머지 R이 0이 될 때까지 반복한다.
  5. 나머지가 0이 되면, 그때의 B가 최초의 A와 B의 최대공약수가 된다.

이 방법은 반복적으로 나머지 연산을 수행하기 때문에 두 수의 차이가 클 때에도 빠른 속도로 최대공약수를 구할 수 있습니다. 또한, 이 알고리즘은 최소공배수를 구하는 데에도 활용된다. 두 수의 곱을 두 수의 최대공약수로 나누면 그 결과가 두 수의 최소공배수가 되기 때문이다.

728x90
반응형
LIST

'알고리즘 > 프로그래머스 JAVA LV.2' 카테고리의 다른 글

멀리 뛰기  (0) 2023.05.24
영어 끝말잇기  (0) 2023.05.23
의상  (0) 2023.05.23
구명보트  (0) 2023.05.23
H-Index  (0) 2023.05.22

+ Recent posts