php 求一个数的约数,刷题2:约数的个数

这篇博客讨论了一道关于计算整数约数个数的编程题,强调了算法优化的重要性。作者最初采用了简单循环的方法,但超时了。后来通过改用平方根优化,将循环限制在`j*j <= temp`,显著提高了效率。博客还提到了不同数据类型的字节大小,并介绍了STL容器如map和vector的使用技巧。
摘要由CSDN通过智能技术生成

题目

题目描述

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

输入描述:

输入的第一行为N,即数组的个数(N<=1000)

接下来的1行包括N个整数,其中每个数的范围为(1<=Num<=1000000000)

当N=0时输入结束。

输出描述:

可能有多组输入数据,对于每组输入数据,

输出N行,其中每一行对应上面的一个数的约数的个数。

示例1

输入

复制

5

1 3 4 6 12

输出

复制

1

2

3

4

6

这道题属于那种不再算法思路上设置障碍,但是对时间要求高,逼着你优化算法的。

我一开始想到的不是这,就是简单的每个数循环,然后cout<

好,那我就建了一个map,只有计算出来的才保存进去,这下这里不会影响性能了吧?没想到还是超

此时就应该能想出来,问题是出在计算的那个环节。试了一下只计算一般,也就是for(int j=1;j<=temp/2;j++),还是超

这个是我写的解法

#include

using namespace std;

mapsaveResult;

int main(){

int n;

int temp;

int count=0;

while(cin>>n){

for(int i=0;i

cin>>temp;

if(saveResult.count(temp)==1)

cout<second<

else{

if(temp==1)

cout<<1<

else{

for(int j=1;j<=temp/2;j++){

if(temp%j==0)

count+=2;

}

cout<

saveResult[temp]=count;

count=0;

}

}

}

}

return 0;

}

最后看别人写的,其实就是在我最原始的算法中改动了一个点,for循环从j<=temp/2变成了j*j

//i*i

#include

using namespace std;

int numOfDivisor(int num)

{

int ans = 0;

int i;

for (i = 1; i*i

{

if (num%i == 0)

ans += 2;

}

if (i*i == num) ans++;

return ans;

}

int main()

{

int n, num;

while (cin >> n)

{

for (int i = 0; i

{

cin >> num;

cout << numOfDivisor(num) << endl;

}

}

return 0;

}

这个改动我是服气的。因为我们要求的其实就是a*b=const,然后找max{min{a,b}},而最大的就是a*a=const,也就是a=sqrt(const)了。所以遍历到这里就可以了。另外,上面的算法还考虑到了,如果是j*j

它也没用动态规划的那一套,如果时间要求更严格些是可以用的。

最后,补充一些相关知识吧:

基本类型所占字节数

32位编译器:

char????? short ? ?? int ? ?? long ? ?? float ? ?? double????? 指针

?? 1??????????? 2?????????? 4???????? 4??????????? 4????????????? 8??????????? 4

64位编译器:

char????? short ? ?? int ? ?? long ? ?? float ? ?? double????? 指针

?? 1??????????? 2?????????? 4?????? ? 8 ?????????? 4????????????? 8??????????? 8

就只有long和指针有区别

STL类型如何随机访问

vector就很方便,下标或者at(int index)就可以

list可以用count()来判断元素是否存在,find()来找到位置,**注意find()返回的是个迭代器,要在前面使用*来取迭代器指向的元素

map可以使用find()返回迭代器,然后使用iter->second来访问迭代器指向的元素

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值