The Way

백준 1131번: 숫자 본문

PS/백준 온라인 저지

백준 1131번: 숫자

Jeonggyun 2018. 1. 10. 15:36

백준 온라인 저지(BOJ) 1131번 문제

https://www.acmicpc.net/problem/1131



1. 문제 요약

자연수 N이 주어졌을 때, N의 각 자리수를 K제곱한 뒤 더하여 수열을 만든다.

A, B, K가 주어졌을 때, A≤N≤B의 N으로 시작하는 수열에서 가장 작은 수의 합을 구하기



2. 알고리즘

쉬워보이는데 생각보다 까다롭다.

다이나믹 프로그래밍 문제인데,


A->B일 때

A로 시작하는 수열의 최솟값 = B로 시작하는 수열의 최솟값 / A 중 작은 값

이 성립한다.


모든 수열은 최종적으로 루프에 도달하게 되는데, 시간관계상 이 루프의 정보들만 미리 구한 뒤 넣어주었다.

합이 10억을 가뿐히 넘기므로 long long을 써야한다.



3. 코드

#include <iostream>
using namespace std;

int K;
int d[1000001] = { 0 };

int cal(int n) {
	int r = 0, t, u;
	while (n) {
		t = 1;
		u = n % 10;
		for (int i = 0; i < K; ++i) t *= u;
		r += t;
		n /= 10;
	}
	return r;
}

int minimal(int n) {
	if (n > 1000000) return minimal(cal(n));
	if (d[n] > 0) return d[n];

	int t = minimal(cal(n));
	return d[n] = t > n ? n : t;
}

int main() {
	int A, B;
	long long sum = 0;
	cin >> A >> B >> K;

	int a[7][20] = { { 0 },
				{ 1, 2, 3, 4, 5, 6, 7, 8, 9 },
				{ 1, 4 },
				{ 1, 371, 153, 55, 370, 160, 407, 919, 136 },
				{ 1, 1138, 8208, 2178, 1634, 9474 },
				{ 1, 24584, 9045, 10933, 9044, 244, 8299, 8294, 58618, 4150, 54748, 93084, 4151, 92727, 89883, 194979 },
				{ 1, 239459, 17148, 282595, 93531, 63804, 548834 } };
	
	int i = 0, n;
	while (a[K][i]) {
		n = a[K][i];
		do {
			if (n <= 1000000) d[n] = a[K][i];
			n = cal(n);
		} while (n != a[K][i]);
		++i;
	}

	for (int i = A; i <= B; ++i) {
		sum += minimal(i);
	}
	cout << sum << endl;

	return 0;
}


'PS > 백준 온라인 저지' 카테고리의 다른 글

백준 14924번: 폰 노이만과 파리  (0) 2018.01.10
백준 2721번: 삼각수의 합  (0) 2018.01.10
백준 2959번: 거북이  (0) 2018.01.10
백준 1904번: 01타일  (0) 2018.01.09
백준 9095번: 1, 2, 3 더하기  (0) 2018.01.09
Comments