網易2018春招筆試程式設計題——nk數對
阿新 • • 發佈:2019-01-07
題目描述:
牛牛以前在老師那裡得到了一個正整數數對(x, y), 牛牛忘記他們具體是多少了。
但是牛牛記得老師告訴過他x和y均不大於n, 並且x除以y的餘數大於等於k。牛牛希望你能幫他計算一共有多少個可能的數對。
首先用兩個for迴圈來暴力求解是可以得到結果,但是時間複雜度太高。所以需要從數學的角度分析,尋找新的思路。
1.首先分析數對的右邊的數。x%y的餘數,其餘數的範圍必定為[0—y-1],所以為了滿足餘數大於等於k,這個y必須為k+1或者更大,x%y的餘數才可能出現k。
2.題目明確為正整數數對,分析x%y與其餘數的關係。可以其餘數是迴圈出現的。
對於一個b, n範圍內的數模b的序列應該是:
0,1,2,...,b-1, 0, 1, 2,..., b-1,...0,1,2,..n%b
比如b為3,n為1-10.
由這個例子,我們可以看出來,1,2,0迴圈出現,完整出現的迴圈有3次,剩下可能有一次不完整的迴圈。
可知,完整迴圈次數為3/10,不完整迴圈的長度為3%10,不管是哪種,都是從1開始的。
#include <bits/stdc++.h> using namespace std; int main() { int n, k; cin >> n >> k; if(k == 0) cout << 1LL * n * n << endl; else { long long ans = 0; for(int i = k + 1; i <= n; i++){ ans += (n / i) * (i - k); if(n % i >= k) ans += n % i - k + 1; } cout << ans << endl; } return 0; }
程式分析:
1.for 迴圈中i變數就是數對的右邊的數
2.對於數對的右邊的數為i的這些數對,只需要分析兩種情況,完整迴圈和不完整迴圈
3.分析完整迴圈:迴圈次數為n/i。因為[0—i-1]是餘數的範圍(但實際出現順序為0在結尾),也是迴圈的範圍,排除前k個數(想象從0開始排除),那麼剩下的餘數肯定是大於等於k的。
4.分析不完整迴圈:只有一次,但長度不定。長度為n%i。分析上面的例子,發現其餘數範圍為[1,2,3,,,,n%i],也是實際出現順序。所以排除前k-1個數(和上面不同的是,這裡是從1開始的,所以只需要排除k-1個數),那麼剩下的餘數都是大於等於k的。所以if的判斷條件為n%i>=k,因為這樣剛好最後一個餘數為k。