어떤 수를 소인수분해 했을 때 그 소인수가 2 또는 3 또는 5로만 이루어진 수를 Ugly Number라고 부릅니다. Ugly Number를 차례대로 적어보면 1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, …….입니다. 숫자 1은 Ugly Number의 첫 번째 수로 합니다. 자연수 N이 주어지면 Ugly Number를 차례로 적을 때 N번째 Ugly Number를 구하는 프로그램을 작성하세요.
입력설명
첫 줄에 자연수 N(3<=N<=1500)이 주어집니다.
10
출력설명
첫 줄에 N번째 Ugly Number를 출력하세요.
12
구현 방식
다중 포인터 알고리즘
곱하기 2 를 해주는 포인터, 곱하기 3을 하는 포인터, 곱하기 5를 하는 포인터를 생성하고, 포인터 자리수을 1로 한다.
현재 포인터 자리수에 위치한 값에서 포인터 값만큼 곱했을 때 최소가 되는 포인터 값을 채택하고 포인터 자리수를 1 추가한다.
이때 최소가 되는 포인터가 여러개면, 똑같이 1추가 시켜준다.
나는 포인터가 p2p3p5 이런식으로 쓰면 코드가 더러울것같아서, 벡터로 만든다음에 for 문을 돌렸는데, 더 더러워진 느낌.
// Pointer 구조체 생성 후 벡터로 사용structPointer{Pointer(){}Pointer(intidx,intvalue){this->idx=idx;this->value=value;}public:intidx=0;intvalue=0;};voidsolution(intN){vector<int>uglyNumbers=vector<int>(N+1,0);uglyNumbers[1]=1;vector<Pointer>pointers=vector<Pointer>{Pointer(1,2),Pointer(1,3),Pointer(1,5)};for(inti=2;i<=N;i++){pair<vector<int>,int>minValue=make_pair(vector<int>(),INT_MAX);for(intj=0;j<pointers.size();j++){intcandidateValue=uglyNumbers[pointers[j].idx]*pointers[j].value;if(minValue.second<candidateValue)continue;if(minValue.second>candidateValue){minValue.first.clear();minValue.first.resize(0);minValue.second=candidateValue;}minValue.first.push_back(j);}uglyNumbers[i]=minValue.second;for(autoit=minValue.first.begin();it!=minValue.first.end();it++)pointers[*it].idx++;}cout<<uglyNumbers[N];}
// 정렬하여 최소값 구한 후 같은 수 포인터 값 증가voidsolution(intN){vector<int>uglyNumbers=vector<int>(N+1,0);uglyNumbers[1]=1;intp2,p3,p5;p2=p3=p5=1;for(inti=2;i<=N;i++){vector<int>candidataValues=vector<int>{uglyNumbers[p2]*2,uglyNumbers[p3]*3,uglyNumbers[p5]*5};sort(candidataValues.begin(),candidataValues.end());if(candidataValues[0]==uglyNumbers[p2]*2)p2++;if(candidataValues[0]==uglyNumbers[p3]*3)p3++;if(candidataValues[0]==uglyNumbers[p5]*5)p5++;uglyNumbers[i]=candidataValues[0];}cout<<uglyNumbers[N];}