BZOJ1263 [SCOI2006]整数划分 高精度
欢迎访问~原文出处——博客园-zhouzhendong
去博客园看该题解
题目传送门 - BZOJ1263
题意概括
将n写成若干个正整数之和,并且使这些正整数的乘积最大。 例如,n=13,则当n表示为4+3+3+3(或2+2+3+3+3)时,乘积=108为最大。
题解
设F(n)为n的乘积ans。
那么有:
F(n) = 3 * F(n - 3) n>4
F(n) = n n<=4
然后压位高精度跑一跑就可以了。
证明我想大家都会吧。
呵呵的我一开始输出了后100位,差错半天……
代码
#include <cstring> #include <cstdio> #include <cstdlib> #include <cmath> #include <algorithm> using namespace std; typedef long long LL; int n,x; struct BigInt{ static const int MaxLen=600; static const LL mod=1e9; int d; LL v[MaxLen]; void Print(){ printf("%lld",v[d]); for (int i=d-1;i>0;i--) printf("%09lld",v[i]); } void operator = (int x){ memset(v,0,sizeof v); d=1,v[1]=x; } BigInt operator * (int x){ BigInt res=*this; for (int i=1;i<=res.d;i++) res.v[i]*=x; for (int i=1;i<=res.d;i++) res.v[i+1]+=res.v[i]/mod,res.v[i]%=mod; while (res.v[res.d+1]>0) res.d++,res.v[res.d+1]=res.v[res.d]/mod,res.v[res.d]%=mod; return res; } void operator *= (int x){ *this=*this*x; } }Ans; int digit(LL x){ int ans=0; while (x) x/=10,ans++; return ans; } int Find_Digit(LL x,int y){ y--; while (y--) x/=10; return x%10; } int main(){ scanf("%d",&n); x=n%3; if (x!=2) x+=3; n=(n-x)/3; Ans=x; for (int i=1;i<=n;i++) Ans*=3; printf("%d\n",(Ans.d-1)*9+(int)(log((double)Ans.v[Ans.d])/log(10)+1)); if (Ans.d>11){ int cnt=digit(Ans.v[Ans.d]),m=100-cnt; printf("%lld",Ans.v[Ans.d]); int i,j; for (i=Ans.d-1;m>9;i--,m-=9) printf("%09lld",Ans.v[i]); for (j=m;j>=1;j--) printf("%d",Find_Digit(Ans.v[i],j+9-m)); } else Ans.Print(); return 0; }