寒武紀第一屆ACM金牌訓練營網路測試賽 C題 math
阿新 • • 發佈:2019-02-10
傳送門:Math
題目大意:
對於一個數對 (a,b),如果滿足 a%b=a/b,則稱這個數對為“好的數對”。 如果 a<=n, b<=n,那麼有多少對數對是“好的數對”呢? (n<=1e9)
輸入樣例:
5
8
3
65
498
513
115
10
80
100
輸出樣例:
3
7
1
131
1556
1611
268
10
172
227
思路:
這個題算是個找規律的題,我們可以寫出滿足條件的前幾項,發現有下表所示規律:
最左側紅色的是 a%b的餘數,其他帶括號的數對的格式為 (a,b),我們發現第一行數對都是 (a,a-1) 的格式;同一列的 b 都是相同的,且從上到下 a 遞增,每次增加的數也相同就是本列最上面的 a 的值。同一行中的餘數相同,且 a 也是遞增的,每次增加的數是這一行的餘數。 此外,第 i 列的數對個數比第 i-1 列多 1.
然後我們來分析一下題目, n 最大為 1e9,時間限制為 1s,大約有 100 組測試樣例,也就是說時間複雜度要小於 O(n).我一開始 for迴圈是按列來的,但是超時了,因為這樣 n 的值沒有減小,後來改成按行來,由於 a%b 的餘數值一定小於 n ,所以大大降低了時間複雜度。這樣只需要確定每行符合條件的數有多少個就可以了。
程式碼:
#include<stdio.h> typedef long long LL; int main() { int i,n,x; LL ans; while(~scanf("%d",&n)) { ans=0; for(i=1;i<=n;i++) { //按行掃描 //每行第一個 a 的值為 i*(i+2) if(n<i*(i+2)) break; //如果當前行沒有符合條件的了則退出 x=(n-i*(i+2))/i+1; //計算當前行滿足條件的數對的個數 ans+=x; } printf("%lld\n",ans); //注意用 long long } return 0; }