AcWing--869.试除法求约数

题目:

给定 n 个正整数 ai,对于每个整数 ai,请你按照从小到大的顺序输出它的所有约数。

输入格式

第一行包含整数 n。

接下来 n 行,每行包含一个整数 ai。

输出格式

输出共 n 行,其中第 i 行输出第 i 个整数 ai 的所有约数。

数据范围

1≤n≤100
1≤ai≤2×10^9

时/空限制

1s / 64MB

输入样例:

2
6
8

输出样例:

1 2 3 6 
1 2 4 8 

分析:

硬写一定会超时,就是因为在求约数的时候重复了,例如a=120,2为他的一个约数,对应的60为他的另一个更大的约数,此时找到了2,也就相当于找到了60,这样节约一般的时间(只用遍历更小的那一半约数)。

代码:

// 只枚举更小的那个约数,节省一般时间,时间复杂度O(n*(a^1/2))
#include <iostream>
#include <algorithm> // 用到了sort()
#include <vector> // 用到了向量vector<int>

using namespace std;

vector<int> get_divisors(int x)
{
    vector<int> res;
    for (int i = 1; i <= x / i; i ++ )
        if (x % i == 0) // 条件成立,即i为x的约数
        {
            res.push_back(i);

// 同时存入另一个约数x/i,节约时间,如x=120,则i=2的时候,同时存入2和60这两个约数
// 注意x是i的平方这个特殊情况
            if (i != x / i) res.push_back(x / i);
        }
    sort(res.begin(), res.end()); // 因为要按从小到大的顺序输出
    return res;
}

int main()
{
    int n;
    cin >> n;

    while (n -- )
    {
        int x;
        cin >> x;
        auto res = get_divisors(x);

        for (auto i : res) // i用于遍历向量,从第一个元素一直遍历到最后一个元素
            cout << i << ' ';
        cout << endl;
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值