Think:
1題意:輸入n, 求(a, b)滿足a < b 且存在x, y使得x*a + y*b = n的二元組個數,要求n, a, b, x, y皆為正整數
2方法:先預先處理小於n的數的約數,然後暴力試探+剪枝,試探符合題意的二元組個數,時間複雜度 1/x 從1到n積分,為nln(n)
vjudge題目連結
建議參考部落格1
建議參考部落格2
以下為Accepted代碼
#include <bits/stdc++.h>using namespace std;const int N = 3e5 + 4;vector <int> y_b[N];vector <int> :: iterator b;int book[N];int main(){ int n, i, j, a, x, t, ans; scanf("%d", &n); for(i = 1; i <= n; i++){ for(j = 1; j*j <= i; j++){ if(i%j == 0){ y_b[i].push_back(j); if(i*i != j){ t = i / j; y_b[i].push_back(t); } } } sort(y_b[i].begin(), y_b[i].end(), greater<int>()); } ans = 0; for(a = 1; a < n; a++){ for(x = 1; x*a < n; x++){ t = n - x*a; for(b = y_b[t].begin(); b != y_b[t].end(); b++){ if((*b) <= a) break; if(book[*b] != a){ ans++; book[*b] = a; } } } } printf("%d\n", ans); return 0;}
以下為建議參考代碼
#include <bits/stdc++.h>using namespace std;const int N = 3e5 + 4;vector <int> y_b[N];/*記錄當前元素的約數*/vector <int> :: iterator b;int book[N];/*實數型全域變數初始化預設為0*/bool cmp(int a, int b){ return a > b;}int main(){ int n, i, j, a, x, t, ans; scanf("%d", &n); for(i = 1; i <= n; i++){ for(j = 1; j*j <= i; j++){ if(i%j == 0){ y_b[i].push_back(j); if(i*i != j){ t = i / j; y_b[i].push_back(t); } } } sort(y_b[i].begin(), y_b[i].end(), greater<int>()); } ans = 0; for(a = 1; a < n; a++){ for(x = 1; x*a < n; x++){ t = n - x*a; for(b = y_b[t].begin(); b != y_b[t].end(); b++){ if((*b) <= a)/*題意:a < b*/ break; if(book[*b] != a){/*標記判重*/ ans++; book[*b] = a; } } } } printf("%d\n", ans); return 0;}