[SCOI2006]整数划分
http://www.lydsy.com/JudgeOnline/problem.php?id=1263
Description
从文件中读入一个正整数n(10≤n≤31000)。要求将n写成若干个正整数之和,并且使这些正整数的乘积最大。 例如,n=13,则当n表示为4+3+3+3(或2+2+3+3+3)时,乘积=108为最大。
Input
只有一个正整数: n (10≤n≤31000)
Output
第1行输出一个整数,为最大乘积的位数。 第2行输出最大乘积的前100位,如果不足100位,则按实际位数输出最大乘积。 (提示:在给定的范围内,最大乘积的位数不超过5000位)。
Sample Input
13
Sample Output
3
108
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
/* http://www.lydsy.com/JudgeOnline/problem.php?id=1263 */ # include <cstdio> # include <cstring> # define N 5000 + 10 int n; char a[N]; int Square(char *s, int len) { int tmp, i, j; char t[N]; memset(t, 0, sizeof(t)); for (i = 0; i < len; ++i) for (j = 0; j < len; ++j) { tmp = t[i+j] + s[i]*s[j]; t[i+j] = tmp % 10; t[i+j+1] += tmp / 10; } memcpy(s, t, sizeof(char)*(2*len)); i = 2*len+2; while (i>0 && s[i] == 0) --i; return i+1; } int Mul(char *s, int x, int len) { int tmp, c, i; c = 0; for (i = 0; i < len; ++i) { tmp = s[i] * x + c; s[i] = tmp % 10; c = tmp / 10; } while (c) { s[i++] = c % 10; c = c / 10; } return i; } int Pow(int base, int power, char *s) { int len = 1; s[0] = 1, s[1] = 0; for (int i = 31; i >= 0; --i) { len = Square(s, len); if ((power>>i) & 0x1) len = Mul(s, base, len); } return len; } void solve(void) { if (n <= 4) { printf("1\n%d\n", n); return ; } memset(a, 0, sizeof(a)); int y = n % 3, x = n / 3; if (y == 1) --x, y = 4; else x = n / 3; int len; len = Pow(3, x, a); if (y) len = Mul(a, y, len); printf("%d\n", len); for (int i = len-1; i>=0 && i>=len-100; --i) putchar(a[i]+'0'); putchar('\n'); } int main() { // freopen("in.txt", "r", stdin); // freopen("out.txt", "w", stdout); while (~scanf("%d", &n)) solve(); return 0; }