vijos1033 整数分解(版本2)

来源:互联网 发布:sql server error 40 编辑:程序博客网 时间:2024/06/07 23:53

题目
一道简单的数论题
题意:把一个整数分解为任意个整数之和,求分解出的整数的积最大值
lc大佬:我们分出尽可能多的2,应该是最优的
然而….
样例:10
->36
2^5=32
被样例被hack了(大雾
正解是:分出尽可能多的3
为什么?
我们考虑两个整数a,b,定义f(x)为分解x所得的积最大值
显然有f(a)*f(b)=f(a+b)
然后我们可以发现
x=2.f(x)=2
x=3.f(x)=3;
x=4.f(x)=4
x=5.f(x)=6
然而,n*2+m*3可以表示出任意一个正整数(除了1)
f(2)=2,f(3)=3
当x=4时,分解出2,2比3,1更优,然而其他情况下,
3^(n/3)+2^(n-n/3*3)总是最优的(这里的除法是下去整的)
因为当没有冗余的1的情况下,取3总是比取2更优
因为如果把3分解为2,1 显然不比一个3更优
因此我们只要特判3种情况:4,3,2

注意用上高精度乘法
然后本题就变成了大水题=_=
然而我第一次提交。。AC:49,TLE:1
lc233:你特判1了吗
………..

#include<iostream>#include<cstdio>#include<cmath>#include<algorithm>#include<queue>#include<string>#include<cstring>#define inf 1e9#define ll long long#define For(i,j,k) for(int i=j;i<=k;i++)#define Dow(i,j,k) for(int i=k;i>=j;i--)using namespace std;int ans[100001];int n;inline void mul(int x){    For(i,1,ans[0])        ans[i]*=x;    For(i,1,ans[0])    {        ans[i+1]+=ans[i]/10;        ans[i]%=10;    }    while(ans[ans[0]+1])    ++ans[0];    while(!ans[ans[0]-1])   --ans[0];}int main(){    scanf("%d",&n);    ans[0]=ans[1]=1;    while (n)    {        if(n>4||n==3)            mul(3),n-=3;        if(n==4)            mul(4),n-=4;        if(n==2)                mul(2),n-=2;        if(n==1)             mul(1),n-=1;    }    Dow(i,1,ans[0]) printf("%d",ans[i]);}
1 0
原创粉丝点击