You want to decorate your floor with square tiles. You like rectangles. With six square flooring tiles, you can form exactly two unique rectangles that use all of the tiles: 1 x 6, and 2 x 3 (6 x 1 is considered the same as 1 x 6. Likewise, 3 x 2 is the same as 2 x 3). You can also form exactly two unique rectangles with four square tiles, using all of the tiles: 1 x 4, and 2 x 2.
Given an integer N, what is the smallest number of square tiles needed to be able to make exactly N unique rectangles, and no more, using all of the tiles? If N = 2, the answer is 4.
There will be several test cases in the input. Each test case will consist of a single line containing a single integer N, which represents the number of desired rectangles. The input will end with a line with a single `0‘.
For each test case, output a single integer on its own line, representing the smallest number of square flooring tiles needed to be able to form exactly N rectangles, and no more, using all of the tiles. The answer is guaranteed to be at most 1018. Output no extra spaces, and do not separate answers with blank lines.
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
typedef long long LL;
LL p[1010];
LL prime[30]= {2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53};
void getartprime(LL cur,int cnt,int limit,int k)
{
//cur:当前枚举到的数;
//cnt:该数的因数个数;
//limit:因数个数的上限;2^t1*3^t2*5^t3……t1>=t2>=t3……
//第k大的素数
if(cur>(1LL<<60) || cnt>150) return ;
if(p[cnt]!=0 && p[cnt]>cur)//当前的因数个数已经记录过且当时记录的数比当前枚举到的数要大,则替换此因数个数下的枚举到的数
p[cnt]=cur;
if(p[cnt]==0)//此因数个数的数还没有出现过,则记录
p[cnt]=cur;
LL temp=cur;
for(int i=1; i<=limit; i++) //枚举数
{
temp=temp*prime[k];
if(temp>(1LL<<60)) return;
getartprime(temp,cnt*(i+1),i,k+1);
}
}
void Init(){
getartprime(1, 1, 75, 0);
for(int i = 1; i <= 75; i++){
if(p[2*i] != 0 && p[2*i-1] != 0) p[i] = min(p[2*i], p[2*i-1]);
else if(p[2*i] != 0) p[i] = p[2*i];
else p[i] = p[2*i - 1];
}
}
int main(){
int n;
Init();
while(scanf("%d", &n) == 1 && n){
printf("%lld\n", p[n]);
}
}