![](/img/trans.png)
[英]Print all the numbers between x & y, & find the average of these numbers
[英]Find the sum of all numbers between 1 and N divisible by either x or y
假設我們有3
數字N
, x
和y
,它們總是>=1
。
N將大於x
和y
, x
將大於y
。
現在我們需要找到1到N之間的所有數字之和,它們可以被x或y整除 。
我想出了這個:
sum = 0;
for(i=1;i<=N;i++)
{
if(i%x || i%y)
sum += i;
}
有沒有更好的方法來找到避免for循環的總和?
我現在已經好好打了很多天,但沒有更好的東西。
如果N
的值具有上限,我們可以使用查找方法來加速該過程。
感謝大家。
我想要一個基於C / C ++的解決方案。 是否有內置函數來執行此操作? 或者我必須編寫算法代碼?
是。 你可以完全取消for循環,並在恆定時間內找到總和。
根據包含 - 排除原理,總結x
倍數和y
倍數,並減去兩次加入的公共倍數,應該給出我們所需的總和。
Required Sum = sum of ( multiples of x that are <= N ) +
sum of ( multiples of y that are <= N ) -
sum of ( multiples of (x*y) that are <= N )
例:
N = 15
x = 3
y = 4
Required sum = ( 3 + 6 + 9 + 12 + 15) + // multiples of 3
( 4 + 8 + 12 ) - // multiples of 4
( 12 ) // multiples of 12
如上所示,我們不得不減去12
,因為它是一個常見的倍數。
整個算法O(1)怎么樣?
令sum(x, N)
是小於或等於N
的x
的倍數之和。
sum(x,N) = x + 2x + ... + floor(N/x) * x
= x * ( 1 + 2 + ... + floor(N/x) )
= x * ( 1 + 2 + ... + k) // Where k = floor(N/x)
= x * k * (k+1) / 2 // Sum of first k natural num = k*(k+1)/2
現在k = floor(N/x)
可以在恆定時間內計算。
一旦知道k
sum(x,N)
就可以在恆定時間內計算sum(x,N)
。
因此,所需的總和也可以在恆定時間內計算。
編輯:
只有當x
和y
是共素時,上述討論才成立。 如果不是,我們需要使用LCM(x,y)
代替x*y
。 有許多方法可以找到LCM,其中一種方法是通過GCD划分產品。 現在GCD不能在恆定時間內計算,但其時間復雜度可以顯着小於線性時間。
如果一個數字可被X整除,則它必須是x的倍數。 如果一個數字可被Y整除,則它必須是y的倍數。
我相信,如果你為x和y的所有倍數做一個for循環,並避免任何重復,你應該得到相同的答案。
在我的腦海中,有類似的東西:
sum = 0
for( i=x; i<=n; i+=x)
sum += i;
for( i=y; i<=n; i+=y)
if( y % x != 0 )
sum += i;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.