编程之美 2.2 不要被阶乘吓到

/* 1 求N! 末尾有多少个0? */

/* 解法一 计算i(i = 1,2,3..N)的因式分解中5的指数 */
int
count(int n)
{
	int ret = 0;
	int i;
	
	for (i = 1; i <= N; i++)
	{
		j = i;
		while (0 == j % 5)
		{
			ret++;
			j /= 5;
		}
	}
	
	return ret;
}

/* 解法二 z = [N/5] + [N/(5*5)] + [N/(5*5*5)].... */
/* [N/5]为N中5的个数,[N/(5*5)]为[N/5]中5的个数 */
/* Z为N!中含有质数5的个数 */
int 
count(int n)
{
	int ret = 0;
	
	while (n)
	{
		ret += N / 5;
		N /= 5;
	}
	
	return ret;
}

/* 2 求N!的二进制表示中最低位1的位置(第一个成为第1位) */
/* 2=(10),每出现一个2,1前进1位,如二进制 10*10*10*10 = (10000) */
/* 等于N! 中含有质数因子2的个数加1 */
int
lastone(int n)
{
	int ret = 0;
	while (n)
	{
		n >>= 1;
		ret += n;
	}
	
	return ret + 1;
}

/* 解法二 N!含有质因子2的个数 等于N减去N的二进制表示中1的数目 */
int
lastone(int n)
{
	return n - bit_1_count(n); 
}

/* 相关题目 判断n是否为2的方幂 */
int
squers(int n)
{
	return n > 0 && ( 0 == (n & (n - 1)));
}


/* 2.3寻找发帖“水王” */
Type Find(Type *ID, int n)
{
	Type candidate;
	int nTimes, i;
	
	for (i = nTimes = 0; i < N; i++)
	{
		if (0 == nTimes)
		{
			candidate = ID[i];
			nTimes = 1;
		}
		else
		{
			if (candidate == ID[i])
			{
				nTimes++;
			}
			else
			{
				nTimes--;
			}
		}
	}
	
	return candidate;
}

/* 扩展问题 */
Type candidate1;
Type candidate2;
Type candidate3;

void find(Type *ID, int n)
{
	int nTimes1 = 0, nTimes2 = 0, nTimes3 = 0;
	int i;
	
	for (i = 0; i < n; i++)
	{
		if (0 == nTimes1)
		{
			candidate1 = ID[i];
			nTimes1++;
		}
		else
		{
			if (candidate1 == ID[i])
			{
				nTimes1++;
			}
			else 
			{
				if (0 == nTimes2)
				{
					candicate2 = ID[i];
					nTimes2++;
				}
				else
				{
					if (candicate2 == ID[i])
					{
						nTimes2++;
					}
					else
					{
						if (0 == nTimes3)
						{
							candicate3 = ID[i];
							nTimes3++;
						}
						else
						{
							if (candicate2 == ID[i])
							{
								nTimes3++;
							}
							else
							{
								nTimes1--;
								nTimes2--;
								nTimes3--;
							}
						}
					}
				}
			}

		}
	}
}
    原文作者:往事已遥远
    原文地址: https://blog.csdn.net/eric43/article/details/7570474
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞