看到题意第一眼想到可以找到n的所有因数遍历一遍取最大最小值。n^3的时间复杂度。。。不会T
#include<bits/stdc++.h>
using namespace std;
const int N =2100;
int main()
{
int64_t n;
while(~scanf("%I64d",&n))
{
int64_t x[N] = {0},l =0;
//想了半天终于想出来logn时间复杂度求一个数所有因数的方法
//其实很简单很简单 √n*√n =n
//遍历√n 再用n除于这个因数不就得到了另一个因数了吗。。。。
for(int i=1; i*i<=n; i++)
{
if(n%i==0)
{
x[l++] =i;
x[l++] =n/i;
}
}
int64_t Min =0x3f3f3f3f3f3f3f3f,Max =-1;
for(int i=0; i<l; i++)
{
for(int j=i; j<l; j++)
{
if(x[i]*x[j]>n)
continue;//不加会T
for(int k=j; k<l; k++)
{
if(x[i]*x[k]*x[j]==n)
{
int64_t t =(x[i]+1)*(x[j]+2)*(x[k]+2);
if(t<Min)
Min =t;
if(t>Max)
Max =t;
t =(x[j]+1)*(x[i]+2)*(x[k]+2);
if(t<Min)
Min =t;
if(t>Max)
Max =t;
t =(x[k]+1)*(x[i]+2)*(x[j]+2);
if(t<Min)
Min =t;
if(t>Max)
Max =t;
}
}
}
}
Min -=n,Max -=n;
printf("%I64d %I64d\n",Min,Max);
}
return 0;
}
看了题解后写的:
我们其实没必要遍历n的所有的因数。
n =3√n3√n3√n
我们可以先取0~3√n内的a,再去找另两个因数即可。
#include<bits/stdc++.h>
using namespace std;
int main()
{
int64_t n;
while(~scanf("%I64d",&n))
{
int64_t Max =-1,Min =0x3f3f3f3f3f3f3f3f;//注意最小值可能答案的最小值很大;
// 假设n的3个因数 a<=b<=c n =a*b*c;
for(int64_t a=1; a*a*a<=n; a++)
{
if(n%a==0)//找到一个因数,再找n/a的两个因数
{
for(int64_t b=a; b*b<=n/a; b++)
{
if((n/a)%b==0)//这里不能写成n%b取余等于零,因为找到的a,b都是n的因数但可能 n/a/b不能整除找不到因数c,想不出数据....
{
int64_t c =n/a/b,t;
//找到a,b,c 三个因数要遍历3种可能情况
t =(a+1)*(b+2)*(c+2);
if(t<Min)
Min =t;
if(t>Max)
Max =t;
t =(b+1)*(a+2)*(c+2);
if(t<Min)
Min =t;
if(t>Max)
Max =t;
t =(c+1)*(a+2)*(b+2);
if(t<Min)
Min =t;
if(t>Max)
Max =t;
}
}
}
}
Max -=n,Min -=n;
printf("%I64d %I64d\n",Min,Max);
}
return 0;
}