計算量比常規計算少很多。
#include<iostream>
#include<math.h>
using namespace std;
int main()
{
int m,n,s=1,i,j,a=0;
while(scanf("%d %d",&m,&n)!=EOF)
{
if(m==0&&n==0)
{
break;
}
if(m>n)
{
int t;
t=m;
m=n;
n=t;
}
for(i=m;i<=n;i++)
{
float tmp;
tmp=sqrt(i);
for(j=2;j<=tmp;j++)
{
if(i%j==0)
{
if(j==i/j)
{
s=s+j;
}
else
{
s=s+j+i/j;
}
}
}
if(i!=1&&i==s)
{
printf("%d ",i);
a=a+1;
}
s=1;
}
if(a==0)
{
printf("No\n");
a=0;
}
else
{
printf("\n");
}
}
return 0;
}
uj5u.com熱心網友回復:
也算是優化了,想想還有優化的空間?uj5u.com熱心網友回復:
至少看到這個程式還有要優化的地方明擺著。uj5u.com熱心網友回復:
一個數的因子集合是被整除的除數與商數的集合。
看優化的地方,用不著寫那么多代碼。
uj5u.com熱心網友回復:
和 += 除數 + 商(= 整數/除數 ) 這是不對的樓主的代碼才對, 要比較 除數 和 商是否相同, 相同的話只能加一個
樓主的代碼核心,就是那兩重回圈,其他的地方都不是重要點
別的地方畢竟只是執行一次, 雙重回圈在m和n數量比較大的情況下,才會有價值
不提改匯編語言實作的事兒,只看演算法
這里可優化的地方還真有一個:
if( j==I/j )
{
s=s+j;
}
else
{
s=s+j+i/j;
}
方案A
int t = I/j;
if( t==j ) s += j; else s += j + t;
這里把兩次 i/j變成了一次
方案B
if ( j*j == I ) s+=j; else s+= j +I/j;
用乘法替代了除法, 除法計算量可不只是乘法的2倍
后面的 s+= j + I/j; 這個除法還是避免不了
考慮到大部分情況下, j*j == i是不成立的, 所以 i/j這個運算被避免的幾率會小
A和B誰更快, 乘法用時/除法用時 和 t==j的幾率 / t!=j 之間誰大了
無論A還是B都比,原來的兩次除法運算效率高。
uj5u.com熱心網友回復:
完美數的確用開方作為結束比較快,優化的地方我沒錯,問題出在結束用商,對于某些數是不適合的,這一點也注意到了,正好這個做了個驗證。
uj5u.com熱心網友回復:
很多數用商是比較接近開方的。uj5u.com熱心網友回復:
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/137652.html
標籤:C++ 語言
