KimMinJun
Coding Note
KimMinJun
전체 방문자
오늘
어제
  • 분류 전체보기 (487)
    • ALGORITHM (11)
      • 정렬 (6)
      • 최단경로 (1)
      • 자료구조 (1)
      • 슬라이딩 윈도우 (1)
      • etc (2)
    • Git (5)
    • Web (24)
      • Vanilla JS (13)
      • TS (2)
      • React (7)
      • ETC (1)
    • React 공식문서 (번역, 공부) (11)
      • Quick Start (2)
      • Installation (0)
      • Describing the UI (9)
      • Adding Interactivity (0)
      • Managing State (0)
      • Escape Hatches (0)
    • Next.js 공식문서 (번역, 공부) (3)
      • Getting Started (2)
      • Building Your Application (1)
    • PS (432)
      • 백준 (187)
      • Programmers (105)
      • CodeUp (21)
      • STL (3)
      • 제코베 JS 100제 (50)
      • SWEA (0)
      • LeetCode (65)
    • IT (1)

블로그 메뉴

  • 홈
  • 태그
  • 방명록
  • 관리

공지사항

인기 글

태그

  • string
  • Level 2
  • Level 1
  • Level 0
  • codeup
  • 정렬
  • C
  • C++
  • LeetCode
  • 백준
  • programmers
  • tree
  • 다이나믹 프로그래밍
  • 수학
  • Level1
  • recursion
  • js
  • 문자열
  • 그래프
  • 제코베 JS 100제

최근 댓글

최근 글

hELLO · Designed By 정상우.
KimMinJun

Coding Note

PS/CodeUp

CodeUp / Recursion(재귀) / 3733번 / 우박수 길이(3n + 1)(large) / C++

2020. 9. 14. 23:59

문제 설명   

콜라츠의 추측, 3n+1 문제, 우박수 문제라고 불리는 이 문제는 다음과 같다.

 

1, 어떤 자연수 n이 입력되면,

2. n이 홀수이면 3n+1을 하고,

3. n이 짝수이면 n/2를 한다.

4. 이 n이 1이 될때까지 2~3과정을 반복한다.

 

예를 들어 5는 5 → 16 → 8 → 4 → 2 → 1 이 된다.

 

여기서 5가 1이되기 위해 6개의 숫자를 나열하게 된다. 이것을 길이라고 하면 5의 길이는 6이된다.

시작수와 마지막 수가 입력되면 그 두 사이게 길이가 가장긴 우박수와 그 길이를 출력하시오.

 

입력

두 자연수 a, b가 공백으로 분리되어 입력된다. ( 1 <= a <= b <= 10,000,000 )

 

출력

a에서 b사이에 길이가 가장긴 우박수와 그 길이를 출력한다. 

만약 가장 긴 수가 두 개이상인 경우, 작은 숫자를 출력하시오.

 

입력 예시

1 10

 

출력 예시

9 20

 

#include <iostream>
using namespace std;

#define N 10000001

// 우박수가 int형의 범위을 넘을수 있으므로 long long int 사용
long long int arr[N] = { 0 };

long long int recursion(long long int k) {
	if (k == 1) return 1;

	if (k > 10000000) { // 지정된 수를 넘을경우 저장은 하지않고 카운트만 올림
		if (k % 2 == 1) return recursion(3 * k + 1) + 1;
		else if (k % 2 == 0) return recursion(k / 2) + 1;
	}

	if (arr[k] != 0) return arr[k]; // 메모이제이션

	else {
		if (k % 2 == 1) return arr[k] = recursion(3 * k + 1) + 1;
		else if (k % 2 == 0) return arr[k] = recursion(k / 2) + 1;
	}
}

int main() {
	int a, b;
	long long int most = arr[0];
	int idx = 0;
	cin >> a >> b;

	for (int i = a; i <= b; i++) {
		if(!arr[i]) recursion(i);

		if (most < arr[i]) { // 최댓값 찾기
			most = arr[i];
			idx = i; // 최댓값의 인덱스 저장
		}
	}

	cout << idx << " " << most << endl;
}

이번 문제는 시간과 오버플로우의 싸움이었다.

이렇게 범위가 클수록 재귀가 시간을 많이 잡아먹기에 메모이제이션을 사용해야 했고,

수가 크므로 int형보다 더 큰 long long int를 써줘야했다.

ex ) 주어진 수가 9999999일 경우 3k+1 이기 때문에 범위를 훨씬 뛰어넘는다.

      이럴 경우엔 저장을 하지않고, 카운트만 올려줬다.

 

저작자표시 (새창열림)

'PS > CodeUp' 카테고리의 다른 글

CodeUp / String(문자열) / 1133번 / 공백이 있는 문자열 입출력 / C++  (0) 2020.09.29
CodeUp / Recursion(재귀) / 4564번 / 계단 오르기 / C++  (0) 2020.09.17
CodeUp / Recursion(재귀) / 3704번 / 계단 오르기2 / C++  (0) 2020.09.14
CodeUp / Recursion(재귀) / 3702번 / 파스칼의 삼각형2 / C++  (0) 2020.09.13
    'PS/CodeUp' 카테고리의 다른 글
    • CodeUp / String(문자열) / 1133번 / 공백이 있는 문자열 입출력 / C++
    • CodeUp / Recursion(재귀) / 4564번 / 계단 오르기 / C++
    • CodeUp / Recursion(재귀) / 3704번 / 계단 오르기2 / C++
    • CodeUp / Recursion(재귀) / 3702번 / 파스칼의 삼각형2 / C++
    KimMinJun
    KimMinJun

    티스토리툴바