您的位置:首页 > 大数据 > 人工智能

Codewars进阶之路——Factorial tail

2017-03-19 21:26 162 查看
题意大概是输入两个数m,n,分别表示进制数(≤256)和底数(≤1000000),求n的阶乘在m进制的表示下最后有几个0

最容易想到的方法如下:

int Zeroes (int base, int number)
{
int f;
for (f = 1; number > 1; f *= number--);
int z = 0;
while (f % base == 0) {
f /= base;
z++;
}
return z;
}


但是很明显一旦number大起来,很容易超出int的表示范围

因此这里就想到另一种方法,思路大致如下:

例如要算10进制下阶乘的结果末尾有几个0,以12为例:

首先,10有素因子2和5,且权值各为1

然后遍历一遍阶乘的每个数,即2~12,针对每个数看看是否能被2或5整除,若能被整除,则记录下整除的次数,如2能被2整除1次,则2对应的记录+1,4能被2整除2次,则2对应的记录+2,5能被5整除1次,则5对应的记录+1,直至遍历结束

最后,将每个素因子被对应的记录做除运算,如这里12的阶乘中,2理论上被记录了10次,5被记录了2次,而2和5的权值都是1,所以最后的结果分别是2和10,取其较小值2,即为最后0的个数

再说16进制也是类似,此时2的权值为4,最后计算n个数中能被2整除的次数,除以4取整即为结果

这里贴出我的代码:

#include <bitset>
#include <map>
#include <cmath>
std::bitset<1000001> num;

void init(int n)
{
for (int i = 2; i <= std::sqrt(n*1.0)+1; ++i)
{
if (num[i] == 0)
{
for (int j = i*i; j <= n; j += i)
num[j] = 1;
}
}
}
int Zeroes(int base, int number)
{
init(number);
std::map<int, int> mp, op;
while (base != 1)
{
for (int i = 2; i <= base; ++i)
if (base%i == 0)
{
base /= i;
mp[i]++;
break;
}
}
for (int i = 2; i <= number; ++i)
{
std::map<int, int>::iterator it;
int tmp = i;
while (tmp != 1)
{
for (it = mp.begin(); it != mp.end(); ++it)
{
int num = it->first;
if (tmp%num == 0)
{
op[num]++;
tmp /= num;
break;
}
}
if (it == mp.end()) break;
}
}
int MIN = 1e10;
std::map<int, int>::iterator it = mp.begin();
for (; it != mp.end(); ++it)
{
int tmp = it->first;
int res = op[tmp] / mp[tmp];
if (res < MIN) MIN = res;
}
return MIN;
}


然后这里出现了另一个问题,因为我的原意是先打个素数表,这样效率应该会高一点,但是一不小心那个素数表没用到,直接就pass了,后来加上了素数表的内容后前一部分代码变为如下内容:

int nm[1000001];

void init(int n)
{
bitset<1000001> num;
for (int i = 2; i <= sqrt(n*1.0)+1; ++i)
{
if (num[i] == 0)
{
for (int j = i*i; j <= n; j += i)
num[j] = 1;
}
}
int pos = 0;
for (int i = 2; i <= n; ++i)
if (num[i] == 0) nm[pos++] = i;
}
int Zeroes(int base, int number)
{
init(number);
map<int, int> mp, op;
int temp = number;
for (int i = 0; nm[i] <= temp;)
if (temp%nm[i] == 0)
{
mp[nm[i]]++;
temp /= nm[i];
}
else i++;


后面都是一样的,但是反而出错了,不知道是什么原因,还望各位不吝告知。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  codewars C++