约数的个数 研招上机题

题目描述

输入n个整数,依次输出每个数的约数的个数

输入描述:

输入的第一行为N,即数组的个数(N<=1000)
接下来的1行包括N个整数,其中每个数的范围为(1<=Num<=1000000000)
当N=0时输入结束。

输出描述:

可能有多组输入数据,对于每组输入数据,
输出N行,其中每一行对应上面的一个数的约数的个数。

示例1

输入

5
1 3 4 6 12

输出

1
2
3
4
6

 写题解之前,我想说下。。。我以为这题就是简单的质数个数定理,然后随便整了个程序,算每个数的所有可行的基的指数,然后把各指数加一,再全部乘起来,然后OJ果断把我TLE了。。。。Scheisse!

后来看了别人的代码,自己写了个,先放我写的AC代码,然后进行证明(因为证明这里,我看网上几乎没有)

#define DEBUG1

#include<iostream>
#include<cstdlib>

int main() {
	std::ios::sync_with_stdio(false);
	int n;
	std::cin >> n;
	for (int i = 0; i < n; i++) {
		int sum = 0;
		int num;
		std::cin >> num;
		int j = 1;
		for (; j * j < num; j++) {
			if (num % j == 0) {
				sum += 2;
#ifdef DEBUG
				std::cout << j << " ";
#endif // DEBUG
			}
		}
		if (j == num) {
#ifdef DEBUG
			std::cout << j << " ";
#endif // DEBUG
			sum++;
		}
		std::cout << sum << std::endl;
	}
#ifdef DEBUG
	system("pause");
#endif // DEBUG

	return 0;
}

下面进行数学证明:(我不是学数分的。。。证明可能有点。。。你懂的)

算法中,使用了折半算约数,那为什么在折半的时候,能整除就可以直接加2呢?

要证明: x的约数个数等于[1, √x)之间能整除x的个数, (最后再判断√x是否是自然数,来决定最后是否加一)

也就是要证明, 如果 a ∈ [1, √x)且a可以整除x,则必有唯一的b = x/a且b∈[√x, x)之间

证:b=x/a = x/f(x) (这丫是泛函吗?不管了,懂这个意思就行), 1/f(x)是单减函数,b ≥ x/√x = √x,

      当b = x时, a = 1,显然b≤x

      所以,b∈[√x, x],且由除法的唯一性可知b是唯一的

      故,如果在[1, √x]之间有约数a存在,则在[√x, 1]一定有一个b = x/a是x的约数

证毕

 

结果:我证明了一个很无聊的东西,应该很多人看一下代码就过了吧,我一直没弄懂,直到我把它证明了。。。故写下来,蠢文共批判,疑义相与析

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值