阶乘

1、先看一个简单的例子

输入不超过1000的正整数n,输出n的阶乘的精确结果。

样例输入:30

样例输出:265252859812191058636308480000000

#include<iostream>
using namespace std;
const int maxn = 3000;//用计算器算算,1000!约等于4*10^2567
int f[maxn];//用3000个元素的数组保存,f[0]对应个位,f[1]对应十位……
int main()//逆序存储是方便进位
{
	int i, j, n;
	cin>>n;
	memset(f,0,sizeof(f));
	f[0]=1;
	for(i=2; i<=n; i++)
	{//乘以i
		int c=0;
		for(j=0; j<maxn; j++)//每次乘以i,进位的处理,程序核心部分
		{
			int s = f[j]*i + c;
			f[j] = s%10;
			c = s/10;
		}
	}
	for(j = maxn-1; j >= 0;j--) if(f[j]) break;//忽略前导 0
	for(i = j; i >= 0; i--)
		cout<<f[i];
	cout<<endl;
	return 0;
}

2、因子和阶乘

问题描述:输入正整数n(2<=n<=100),把n的阶乘分解乘素因子相乘的形式,从小到大输出各个素数(2,3,5,……)的

指数。例如825=3*5^2*11应表示成(0,1,2,0,1)表示分别有0、1、2、0、1个2、3、5、7、11。你的程序应忽略比最大因子更大的素数(否则末位会有很多个0)

样例输入:

5

53

样例输出:

5!= 3 1 1

53! = 49 23 12 8 4 4 3 2 2 1 1 1 1 1 1 1 

#include<iostream>
using namespace std;
int is_prime(int n)//is_prime不能用于n特别大的情况,因为存在越界的可能
{
	for(int i=2; i*i <= n; i++)
		if(n % i ==0) return 0;
	return 1;
}
//素数表
int prime[100], count = 0;
int main()
{
	int i, n, p[100];//n和各个素数的指数
	//构造素数表
	for(i=2; i<=100; i++)
		if(is_prime(i)) prime[count++] = i;
	while(cin>>n)
	{
		cout<<n<<"! =";
		memset(p, 0, sizeof(p));
		int maxp=0;
		for(i=1; i<=n; i++)
		{
			int m =i;//把i赋值给m,从而做除法时不会修改它的值
			for(int j =0; j < count; j++)
				while(m % prime[j] == 0)
				{
					m /= prime[j];//反复除以prime[j],并累加p[j]
					p[j]++;
					if(j>maxp) maxp=j;//更新最大因子的下标
				}
		}
		for(i=0; i<=maxp; i++)//只循环到最大因子的下标
			cout<<" "<<p[i];
		cout<<endl;
	}
	return 0;
}

3、N的阶乘末尾有多少个0

分析:N! = K * 10^M,其中K不能被10整除,知N!末尾有M个0。考虑对N!进行质因子分解,N!=(2^X)*(3^Y)*(5^Z)…

由于10=2*5,于是M=min(X,Z),不难看出X>=Z(被2整除的数出现的频率比能被5整除的数出现的频率高的多),原问题

可简化为求因式分解中5的指数。

#include<iostream>
using namespace std;
int main()
{
	int i, j, N, ret; 
	cin>>N;
	/*另一种求Z的方法Z=[N/5]+[N/5^2]+[N/5^3]+…
	ret=0;
	while(N)
	{
	ret + =N/5;
	N /= 5;
	}
	*****************************************************/
	ret = 0;
	for(i=1;i<=N; i++)
	{
		j=i;
		while(j % 5 == 0)
		{
			ret++;
			j /= 5;
		}
	}
	cout<<ret<<endl;
	return 0;
}


Z为N!中含有质因子5的个数,Z=[N/5]+[N/5^2]+[N/5^3]+…

4、求N!的二进制表示中最低位1的位置。

  1. 等价于N!中含有质因子2的个数加1(此结论由一个二进制数除以2的过程总结而得)
  2. N减去N的二进制表示中1的数目
    假设N=11011,那么N!中质因子2的个数为[N/2]+[N/4]+[N/8]+[N/16]+…
    即: 1101+110+11+1
        =(1000+100+1)+(100+10)+(10+1)+1
        =(1000+100+10+1)+(100+10+1)+1
        =1111+111+1
        =(10000-1)+(1000-1)+(10-1)+(1-1)
        =11011-(N二进制表示中1的个数)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值