高精,拆分
要求整数划分,且积越大,就如同矩形周长划分求面积最大,那么就是正方形最大,即越平均答案越大。
于是,将一个数划分,就是不断分成两份的过程,如果是奇数则为n/2和n/2+1,偶数则为n/2和n/2,最终结果必定是x个3和y个2。
由于2^3=8,2+2+2=6,而3^2=9,3+3=6,如果遇到3个2则用两个3替换
代码
#include<iostream>
#include<queue>
#include<cstring>
#include<cstdio>
#include<cctype>
#include<algorithm>
using namespace std;
long long n;
queue<long long>q;
int f[50005],cnt=1;//储存原数
int a[50005];//进位数组
int c2,c3;
void change(int x)
{
for(int i=1;i<cnt;++i)
{
f[i]*=x;
if(f[i]>=10)
{
a[i+1]=f[i]/10;
f[i]=f[i]%10;
}
}//第一次乘和进位处理,一定要开一个数组不然会把进位的数一起做下一次乘法
f[cnt]*=x;
if(f[cnt]>=10)
{
a[cnt+1]=f[cnt]/10;
f[cnt]=f[cnt]%10;
cnt++;
}//当超出当前最大位数时要加特判进位,并更新最大位数cnt
for(int i=1;i<=cnt;++i)
{
f[i]=a[i]+f[i];
if(f[i]>=10)
{
f[i+1]+=f[i]/10;
f[i]=f[i]%10;
if(i==cnt) cnt++;
}
} //加上进位的数,并且也要判断是否需要进位
memset(a,0,sizeof(a));//用完清零
}
int main()
{
scanf("%d",&n);
q.push(n);
while(!q.empty())
{
int x=q.front();q.pop();
if(x==2||x==3)
{
(x==2)?c2++:c3++;
continue;
}
q.push(x/2);
q.push(x-x/2);
}//队列分解因数
if(c2>=3)
{
c3+=c2/3*2;
c2=c2%3;
}//用3替换2
f[1]=1;//初值不能为0
for(int i=1;i<=c3/2;++i)
change(9); //由于我的算法为一位乘多位,3也是乘,9也是乘,不如用9替换3可以节约一点时间
if(c3%2!=0)
change(3);//多出的3要乘回
if(c2!=0)//这里一定要特判,在下因为没特判碰见3的倍数就全部输出0
change(c2*2);
cout<<cnt<<endl;
reverse(f+1,f+cnt+1);//数组翻转,其实无所谓,只不过看起来舒服
for(int i=1;i<=min(100,cnt);i++)
cout<<f[i];
}
其实这题直接拿一个模板做也非常简单,只不过既然都拆分开了不如直接做,而且一位乘多位代码实现也比多位乘多位简单易懂的多。