zl程序教程

您现在的位置是:首页 >  其它

当前栏目

【bzoj1263】[SCOI2006]整数划分 高精度

整数 划分 高精度
2023-09-11 14:22:40 时间

题目描述

从文件中读入一个正整数n(10≤n≤31000)。要求将n写成若干个正整数之和,并且使这些正整数的乘积最大。 例如,n=13,则当n表示为4+3+3+3(或2+2+3+3+3)时,乘积=108为最大。

输入

只有一个正整数: n (10≤n≤31000)

输出

第1行输出一个整数,为最大乘积的位数。 第2行输出最大乘积的前100位,如果不足100位,则按实际位数输出最大乘积。 (提示:在给定的范围内,最大乘积的位数不超过5000位)。

样例输入

13

样例输出

3
108


题解

高精度

首先根据某小学奥数理论,如果n%3==0,则全拆成3;如果n%3==1,则拆出来一个4,其余全拆成3;如果n%3==2,则拆出来一个2,其余全拆成3.

然后高精度乘低精度就好了。

由于有位数限制,所以比较懒没有压位,可能会慢点。

#include <cstdio>
#include <cstring>
struct data
{
	int len , num[5010];
	data()
	{
		len = 0 , memset(num , 0 , sizeof(num));
	}
	data operator=(const int a)
	{
		len = 1 , num[0] = a;
		return *this;
	}
	data operator*(const int a)const
	{
		data t;
		int i;
		for(i = 0 ; i < len ; i ++ ) t.num[i] += num[i] * a , t.num[i + 1] += t.num[i] / 10 , t.num[i] %= 10;
		t.len = len + (bool)t.num[len];
		return t;
	}
	void output()
	{
		printf("%d\n" , len);
		int i;
		for(i = len - 1 ; i >= 0 && i >= len - 100 ; i -- ) printf("%d" , num[i]);
		printf("\n");
	}
}ans;
int main()
{
	int n , i;
	scanf("%d" , &n);
	ans = (n + 1) % 3 + 2;
	for(i = 1 ; i <= (n - 2) / 3 ; i ++ ) ans = ans * 3;
	ans.output();
	return 0;
}