整数划分(sum.pas/c/cpp)
【题目描述】
从文件中读入一个正整数n(10≤n≤31 000)。要求将n写成若干个正整数之和,并且使这些正整数的乘积最大。 例如,n=13,则当n表示为4+3+3+3(或2+2+3+3+3)时,乘积=108为最大。
【输入格式】(sum.in):
一个整数,n
【输出格式】(sum.out):
第1行输出一个整数,为最大乘积的位数。 第2行输出最大乘积的前100位,如果不足100位,则按实际位数输出最大乘积。 (提示:在给定的范围内,最大乘积的位数不超过5000位)。
【输入样例】
13
【输出样例】
3
108
呃,话说这是一个很经典的规律: 3 越多越好,如果剩下了 1 ,就与最后一个 3 拼成 4 ,如果剩下了 2 ,就直接 *2 。。。。。。。
然后,就是高精了。
代码(SueMiller)
program ACRush;
type arr=array[0..6000]of longint;
var n,nn:longint;
i,j,k,l,r,mid,ll,rr:longint;
ans:arr;
procedure mul(b:longint);
var i:integer;
begin
for i:=1 to ans[0] do
ans[i]:=ans[i]*b;
for i:=1 to ans[0] do
begin
ans[i+1]:=ans[i] div 10+ans[i+1];
ans[i]:=ans[i] mod 10;
end;
while ans[ans[0]+1]>0 do
begin
inc(ans[0]);
ans[ans[0]+1]:=ans[ans[0]] div 10;
ans[ans[0]]:=ans[ans[0]] mod 10;
end;
end;
begin
assign(input,'sum.in');reset(input);
assign(output,'sum.out');rewrite(output);
readln(n);
ll:=0;rr:=0;
l:=2;r:=n>>1;
i:=n div 3;
fillchar(ans,sizeof(ans),0);
ans[1]:=1;
ans[0]:=1;
if n mod 3=0 then
begin
k:=3;
for j:=1 to i do
mul(k);
end
else begin
nn:=n-n div 3*3;
for j:=1 to i-1 do
begin
mul(3);
end;
if nn=2 then
begin
mul(3);
mul(nn);
end
else begin
mul(4);
end;
// for j:=1 to i do write(d[j],' ');
// writeln;
// for j:=ans[0] downto 1 do write(ans[j]);
// writeln;
end;
writeln(ans[0]);
if ans[0]>100 then
begin
for i:=ans[0] downto ans[0]-100+1 do
write(ans[i]);
writeln;
end
else begin
for i:=ans[0] downto 1 do
write(ans[i]);
writeln;
end;
close(input);close(output);
end.