亲密数字(number)

我这超时了请问大家这怎样更简便
【运行时限】:3秒。

假设两个不同的正整数A和B是亲密数字,那么有如下的性质:①整数A的全部真约数(包括1,不包括A本身)之和等于B;②整数B的全部真约数(包括1,不包括B本身)之和等于A。

举个例子,对于220和284这一对亲密数字来说:

220的全部真约数有:1+2+4+5+10+11+20+22+44+55+110 = 284
284的全部真约数有:1+2+4+71+142 = 220
请你编写一个程序,从键盘输入正整数X和Y(2≤X≤Y≤32767),在屏幕分行输出X和Y之间所有的成对亲密数字,中间用空格隔开,同时要保证小数在前,大数在后。

输入输出格式
输入
输入一行,包含两个正整数X和Y(2≤X≤Y≤32767),中间用空格隔开。

输出
输出多行,对应多组亲密数字,每行包含两个正整数,即X和Y之间所有的成对亲密数字,中间用空格隔开。

样例
输入1
2 1000
输出1
220 284
时间及空间限制
1s, 256MB.
我编的代码:

#include <bits/stdc++.h>
using namespace std;
int main()
{
    int x,y,i,j,s=0,s2=0;
    cin>>x>>y;
    for(i=x;i<=y;i++)
    {
        s=0;s2=0;
        for(j=1;j<i;j++)
        {
        if(i%j==0)
        {
            s=s+j;
        }
            
        }
    
        if(s>=x&&s<=y)
        {
            for(j=1;j<s;j++)
            {
                if(s%j==0)
                {
                    s2=s2+j;
                }
            }
            if(s2==i&&i<s)
            {
                cout<<i<<" "<<s<<endl;
            }
        }
    }
}


img

求回复。

求约数和可以降到O(sqrt(n))的级别。

更新思路:枚举A,先求A的约数和tmp,然后求tmp的约数和t2,若t2=A,则A和tmp是亲密数。

优化后代码如下:

#include <bits/stdc++.h>
using namespace std;
int x, y;
int main() {
    scanf("%d%d", &x, &y);
    for (int i = x; i <= y; i++) {
        int tmp = 1, lm1 = sqrt(i);
        for (int j = 2; j <= lm1; j++)
            if (i % j == 0)
                tmp += j + i / j;
        if (lm1 * lm1 == i) tmp -= lm1;
        if (i >= tmp) continue;
        int t2 = 1, lm2 = sqrt(tmp);
        for (int j = 2; j <= lm2; j++)
            if (tmp % j == 0)
                t2 += j + tmp / j;
        if (lm2 * lm2 == tmp) t2 -= lm2;
        if (t2 == i) printf("%d %d\n", i, tmp);
    }
    return 0;
}

经测试,时间复杂度大约为O(n*sqrt(n)),32768稳过。