快速求N!

3 篇文章 0 订阅

快速求N的阶乘

最近老师布置了一个作业1s内求20000!的阶乘

阶乘超过40
思路肯定就是数组,真正让我为难的是1s内。

最后想出来了一个勉强1s内。

开o2优化,x64

//#include"My_head.h"
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<windows.h>
#include <assert.h>    //设定插入点
#include <ctype.h>     //字符处理
#include <errno.h>     //定义错误码
#include <float.h>     //浮点数处理
#include <iso646.h>        //对应各种运算符的宏
#include <limits.h>    //定义各种数据类型最值的常量
#include <locale.h>    //定义本地化C函数
#include <math.h>     //定义数学函数
#include <setjmp.h>        //异常处理支持
#include <signal.h>        //信号机制支持
#include <stdarg.h>        //不定参数列表支持
#include <stddef.h>        //常用常量
#include <stdio.h>     //定义输入/输出函数
#include <stdlib.h>    //定义杂项函数及内存分配函数
#include <string.h>    //字符串处理
#include <time.h>     //定义关于时间的函数
#include <wchar.h>     //宽字符处理及输入/输出
#include <wctype.h>    //宽字符分类

#pragma once

#include"My_head.h"

long long maxsize;
long long nbitcount;
long long nbitcount1;
long long* init(long long n);
void mul(long long x, long long* s);
void print_arr(long long* s, long long x);

int main()
{
	int begintime, endtime;
	long long* ps = NULL;
	long long n;
	printf("请输入一个非负数n\r\n");
	scanf("%lld", &n);
	begintime = clock();//计时开始
	if (n < 0)
	{
		printf("输入错误,退出程序");
		exit(0);
	}

	if (n == 0)
		n = 1;
	ps = init(n);//根据n申请空间
	for (long long i = 1; i <= n; i++)
	{
		mul(i, ps);
	}
	print_arr(ps, nbitcount);
	endtime = clock();	//计时结束
	printf("\n\nRunning Time:%dms\n", endtime - begintime);


}

void mul(long long x, long long* s)
{	long long temp = 0;

	for (long long i = maxsize-1; i >= nbitcount; i--)
	{
		s[i] *= x;
		s[i] += temp;
		temp = s[i] / 100000000000000;
		s[i] = s[i] % 100000000000000;
		//记录实时位数,减少时间
		if (temp != 0)
		{
			nbitcount1 = i - 1;
			if (nbitcount > nbitcount1)
			{
				nbitcount = nbitcount1;

			}

		}
	}
}
long long* init(long long n)
{
	double nbitcount2 = 0;
	for (long long i = 1; i <= n; i++)
	{
		nbitcount2 += (double)log10(i);
	}
	maxsize = ceil( ceil(nbitcount2) /14)+1;
	nbitcount1 = nbitcount = maxsize;
	nbitcount--;
	long long* ps = (long long*)malloc(sizeof(long long) * maxsize);
	for (long long i = 0; i <maxsize-1 ; i++)
		ps[i] = 0;

	ps[maxsize-1] = 1;

	return ps;
}
void print_arr(long long* s, long long x)
{	printf("其阶乘为:");
	printf("%lld", s[x]);
	for (long long i = x + 1; i <maxsize; i++)
	{
		printf("%014lld", s[i]);
	}
	printf("\n");
}

最后发现控制台一打印就寄了,改成输出到文本就可以看了,具体加

1.exe >1.txt

最后发现一牛人,优化到0.014s

https://www.emath.ac.cn/algorithm/factorial.htm

这里是挑出 2和5 补0,一下子就快起来了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值