cf 143C Help Farmer 题解

看到题意第一眼想到可以找到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;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值