hduoj_1042(大数阶乘)

在这道题上浪费了很长时间。

自己写的很不好。时间和空间均超出限制,虽然最后的结果是正确的。

下面是自己的代码。

#include<stdio.h>
#include<string.h>

char n[10001][36000];

int max;

void calculate(int i)
{
	char temp[10];
	memset(temp, 0, sizeof(temp));

	int a = i, b = i + 1;
	int c = 0;

	while (b != 0)
	{
		temp[c++] = (b % 10) + '0';
		b = b / 10;
	}

	b = i + 1;
	int la = strlen(n[a]);
	int lb = strlen(temp);

	int p, q, r;
	int bit = 0;

	char mul[36000];
	for (p = 0; p < lb; p++)
	{
		memset(mul, 0, sizeof(mul));

		r = p;

		bit = 0;
		
		for (q = 0; q < la; q++)
		{
			mul[r++] = (bit + (n[a][q] - '0')*(temp[p] - '0')) % 10 + '0';
			bit = ((n[a][q] - '0')*(temp[p] - '0') + bit) / 10;
		}

		int s1;

		if (bit)
		{
			mul[r] = bit + '0';
			s1 = r + 1;
		}
		else
			s1 = r;
			
		
		// add
		
		int s2 = strlen(n[b]);

		int s = s1 > s2 ? s1 : s2;

		bit = 0;
		for (q = 0; q < s; q++)
		{
			mul[q] = mul[q] == '\0' ? '0' : mul[q];
			n[b][q] = n[b][q] == '\0' ? '0' : n[b][q];

			int temp_bit = bit;
			bit = ((n[b][q] - '0') + (mul[q] - '0') + bit) / 10;

			n[b][q] = (((n[b][q] - '0') + (mul[q] - '0') + temp_bit) % 10) + '0';
			
		}
		if (bit)
			n[b][q] = '1';
	}
	
}

int main()
{
	int m;
	int i;

	memset(n, 0, sizeof(n));
	strncpy(n[0], "1", 1);
	strncpy(n[1], "1", 1);
	max = 1;

	while (EOF != scanf("%d", &m))
	{
		if (max < m)
		{
			for (i = max; i <= m - 1; i++)
				calculate(i);

			max = m;
		}
		

		for (i = strlen(n[m]) - 1; i >= 0; i--)
		{
			if ('0' == n[m][i])
				printf("0");
			else
				printf("%c", n[m][i]);
		}
			
		printf("\n");
	}
	return 0;
}

鼓励一下自己:实实在在的努力,没有水分的成功,总是震撼人心的风景。


此处小结。

我以前做大数有关的题目时,都是把一个大数作为一个字符串处理,大数的一位数字是字符串的一个字符。

现在学会了新的方法。

万进制。用一个int作为万进制的一位。当然千进制等依此类推。

读了题解后,得到下面的方法。最后改来改去,自己的代码几乎和题解一样。当作模板用吧。


首先是10进制。时间卡的很紧。MAX设为40000超时,36000就通过了。

#include <stdio.h>
#include <string.h>

#define BASE 10
#define MAX 36000
int r[MAX];

int main()
{
	int n;
	int i, j;
	int bit;

	while (EOF != scanf("%d", &n))
	{
		memset(r, 0, sizeof(r));

		r[0] = 1;
		
		for (i = 2; i <= n; i++)
		{
			bit = 0;
			for (j = 0; j < MAX; j++)
			{
				r[j] = r[j] * i + bit;
				bit = r[j] / BASE;
				r[j] = r[j] % BASE;
			}
		}

		for (i = MAX - 1; i >= 0; i--)
		{
			if (r[i])
				break;
		}

		for (j = i; j >= 0; j--)
			printf("%d", r[j]);
		printf("\n");
	}
		
	return 0;
}


再尝试一下万进制。主要区别是BASE和MAX。

其中用到了printf("%04d"), 解释如下。

%nd 输出的整型宽度至少为n位,右对齐,%5d即宽度至少为5位,位数大于5则输出实际位数
%0nd 用得比较多,表示输出的整型宽度至少为n位,不足n位用0填充
printf("%05d",1)输出:00001

printf("%5d",1)输出:****1(*为空格)


附上代码。

#include <stdio.h>
#include <string.h>

#define BASE 10000
#define MAX 9000
int r[MAX];

int main()
{
	int n;
	int i, j;
	int bit;

	while (EOF != scanf("%d", &n))
	{
		memset(r, 0, sizeof(r));

		r[0] = 1;
		
		for (i = 2; i <= n; i++)
		{
			bit = 0;
			for (j = 0; j < MAX; j++)
			{
				r[j] = r[j] * i + bit;
				bit = r[j] / BASE;
				r[j] = r[j] % BASE;
			}
		}

		for (i = MAX - 1; i >= 0; i--)
		{
			if (r[i])
				break;
		}

		for (j = i; j >= 0; j--)
		{
			if(j == i)
				printf("%d", r[j]);
			else
				printf("%04d", r[j]);
		}
			
		printf("\n");
	}
		
	return 0;
}

时间大概是10进制的1/3到1/4。


先写到这里。

晚上回去的时候配置一下Java环境。尝试一下Java的大数类。






猜你喜欢

转载自blog.csdn.net/qq_32862515/article/details/80713235