[백준] 1904. 01타일

진예·2023년 12월 13일
0

Baekjoon : JAVA

목록 보기
72/76
post-thumbnail

📌 문제

[1904] 01타일

지원이에게 2진 수열을 가르쳐 주기 위해, 지원이 아버지는 그에게 타일들을 선물해주셨다. 그리고 이 각각의 타일들은 0 또는 1이 쓰여 있는 낱장의 타일들이다.

어느 날 짓궂은 동주가 지원이의 공부를 방해하기 위해 0이 쓰여진 낱장의 타일들을 붙여서 한 쌍으로 이루어진 00 타일들을 만들었다. 결국 현재 1 하나만으로 이루어진 타일 또는 0타일을 두 개 붙인 한 쌍의 00타일들만이 남게 되었다.

그러므로 지원이는 타일로 더 이상 크기가 N인 모든 2진 수열을 만들 수 없게 되었다. 예를 들어, N=1일 때 1만 만들 수 있고, N=2일 때는 00, 11을 만들 수 있다. (01, 10은 만들 수 없게 되었다.) 또한 N=4일 때는 0011, 0000, 1001, 1100, 1111 등 총 5개의 2진 수열을 만들 수 있다.

우리의 목표는 N이 주어졌을 때 지원이가 만들 수 있는 모든 가짓수를 세는 것이다. 단 타일들은 무한히 많은 것으로 가정하자.

⬇️ 입력

첫 번째 줄에 자연수 N이 주어진다. (1 ≤ N ≤ 1,000,000)

⬆️ 출력

첫 번째 줄에 지원이가 만들 수 있는 길이가 N인 모든 2진 수열의 개수15746으로 나눈 나머지를 출력한다.

💡 코드


동적 계획법은 특정 규칙을 담은 점화식을 기준으로 문제를 풀어나가기 때문에 무작위로 써서 규칙을 찾아봤는데,, 개수피보나치 수열 형태로 증가하는 걸 발견할 수 있었다!

어제 풀었던 피보나치 수열 문제와 같이 Bottom-up 접근을 통해 풀었는데 오답 처리가 됐다,,

import java.io.*;
import java.util.*;
public class Main {
	
	static int[] arr;

	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));

		int n = Integer.parseInt(br.readLine());
		arr = new int[n];
		
		bw.write(fibo(n) % 15746 + "");
		
		br.close();
		bw.close();
	}
	
	static int fibo(int n) {
		arr[0] = 1; arr[1] = 2;
		
		for(int i=2;i<n;i++) {
			arr[i] = arr[i-1] + arr[i-2];
		}
		return arr[n-1];
	}
}

❌ 혹시나 싶어서 1을 넣어봤는데 인덱스 범위 초과 예외가 발생했다! n = 1인 경우에는 arr[1]을 참조할 수 없으므로, n = 1인 경우에는 1을 리턴할 수 있도록 조건문을 추가해주니 제대로 1을 리턴했으나,, 여전히 오답 처리,,

...
	
	static int fibo(int n) {
		
		if(n == 1) return 1;
		
		arr[0] = 1; arr[1] = 2;
		
		for(int i=2;i<n;i++) {
			arr[i] = (arr[i-1] + arr[i-2])
		}
		return arr[n-1];
	}
}

✅ 원인을 도저히 모르겠어서 구글링 해 본 결과 대부분의 사람들이 나머지 연산 % 15746을 출력문이 아닌 수열을 구하는 과정에서 수행하고 있었다. 솔직히 처음에 문제 봤을 때부터 왜 나머지 연산을 굳이 하나 싶었는데 입력 범위가 1,000,000까지이기 때문에 오버플로우가 발생할 수 있어서 그런 거였다!

애초에 수열을 구할 때 나머지 연산을 수행하면 나머지가 저장되어 오버플로우가 발생하지 않겠지만, 오버플로우가 발생한 상태에 나머지 연산을 수행하면 값이 달라질 수 밖에 없다.

import java.io.*;
import java.util.*;
public class Main {
	
	static int[] arr;

	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));

		int n = Integer.parseInt(br.readLine());
		arr = new int[n];
		
		bw.write(fibo(n) + "");
		
		br.close();
		bw.close();
	}
	
	static int fibo(int n) {
		
		if(n == 1) return 1;
		
		arr[0] = 1; arr[1] = 2;
		
		for(int i=2;i<n;i++) {
			arr[i] = (arr[i-1] + arr[i-2]) % 15746;
		}
		return arr[n-1];
	}
}

profile
백엔드 개발자👩🏻‍💻가 되고 싶다

0개의 댓글