标签:高精度
Description
Input
Output
Sample Input
2
Sample Output
2 3
解题思路:
题目大意是财产分割,每个人分的钱从前往后越来越少,最后必须给教堂留一部分最少的钱。这题第一个人一定只能拿1/2,后面一个人只能拿剩下的1/2,而由于要给教堂留一部分钱所以最多只能拿1/3,接着下一个人只能拿剩下的1/6,由于也要给教堂留一部分钱,所以最多只能拿1/7,因此每个人拿的钱都是从剩下的1/x中拿走1/(x + 1)。通过类比归纳可以发现如果第n-1个人拿了1/a,则第n个人拿了1/((a - 1)*a + 1)。虽然公式很简单,是一个数列,但动笔写写就会发现,越往后,数字越大,成指数倍增长,必须得用高精度来做。数组开多大可以计算一下,我算出第18个数位数最多达到2^15个,所以开5万数组应该是够了。不过我依然开了10万,多开总比开少了好嘛。。。一开始把数组全初始化,控制前导零来做,结果TLE了,还是考虑过于简单,10万数组初始化来做高精度不TLE才怪呢。还是老老实实地去计算每个数的位数吧,总算AC了。。。。为了达到种种目的导致代码写得很挫,不过AC才是王道嘛。
AC代码:
#include <iostream> #include <cstdio> #include <cstring> using namespace std; const int maxn = 50000; int a[20][maxn], b[maxn], len[20]; void Fun(int n) { a[1][0] = 2; len[1] = 1; for(int i = 2; i <= n; i++) { int len_1 = len[i - 1]; int d = 0; for(int j = 0; j < len_1; j++) { if(j == 0) b[0] = a[i - 1][0] - 1; else b[j] = a[i - 1][j] + d; if(b[j] < 0) { b[j] += 10; d = -1; } else d = 0; } for(int j = 0; j < len_1; j++) for(int k = 0; k < len_1; k++) a[i][j + k] += a[i - 1][j] * b[k]; a[i][0] += 1; a[i][len_1 * 2 - 1] = 0; for(int j = 0; j < len_1 * 2 - 1; j++) { if(a[i][j] >= 10) { a[i][j + 1] += a[i][j] / 10; a[i][j] %= 10; } } if(a[i][len_1 * 2 - 1]) len[i] = len_1 * 2; else len[i] = len_1 * 2 - 1; } } int main() { int n; scanf("%d", &n); Fun(n); for(int j = 1; j <= n; j++) { for(int i = len[j] - 1; i >= 0; i--) { printf("%d",a[j][i]); } printf("\n"); } return 0; }
标签:高精度
原文地址:http://blog.csdn.net/userluoxuan/article/details/38316257