《戰神4》前期技能加點推薦 什麼技能好用
阿新 • • 發佈:2022-01-30
目錄
題目描述
題目描述
出題是一件痛苦的事情!
相同的題目看多了也會有審美疲勞,於是我捨棄了大家所熟悉的 A+B Problem,改用 A-B 了哈哈!
好吧,題目是這樣的:給出一串數以及一個數字 CC,要求計算出所有 A - B = CA−B=C 的數對的個數(不同位置的數字一樣的數對算不同的數對)。
輸入格式
輸入共兩行。
第一行,兩個整數 N, CN,C。
第二行,NN 個整數,作為要求處理的那串數。
輸出格式
一行,表示該串數中包含的滿足 A - B = CA−B=C 的數對的個數。
輸入輸出樣例
輸入 #1複製
4 1 1 1 2 3
輸出 #1複製
3
說明/提示
對於 75%75% 的資料,1 \leq N \leq 20001≤N≤2000。
對於 100%100% 的資料,1 \leq N \leq 2 \times 10^51≤N≤2×105。
保證所有輸入資料絕對值小於 2^{30}230,且 C \ge 1C≥1。
2017/4/29 新添資料兩組
演算法求解
分析
-
首先對給的陣列a排序
-
然後用b陣列記錄每個數字及其出現次數(也是按照數字大小排序的)
-
遍歷每種數字,對每種數字x,自己的數量是num1,二分查詢b中有沒有 x + c這個數字,有的話返回其數量num2,沒有返回-1
-
那麼如果存在x+c,且其數量為num2,則這兩種陣列成的數對數量為num1 * num2
程式碼
#include<iostream> #include<cstdio> #include<algorithm> #include<vector> using namespace std; typedef pair<int, int> PII; typedef long long LL; const int N = 200010; int a[N]; vector<PII> b; int n, c; int find(int x) { int l = 0, r = b.size(); while(l < r) { int mid = (r + l) >> 1; if(b[mid].first >= x) r = mid; else l = mid+1; } if(b[l].first != x) return -1; else return b[l].second; } int main() { scanf("%d%d", &n, &c); for(int i = 0; i < n; i++) { scanf("%d", &a[i]); } sort(a, a + n); int cnt = 0; for(int i = 0; i < n; i++) { if(i && a[i] != a[i-1]) { b.push_back({a[i-1], cnt}); cnt = 0; } cnt++; } b.push_back({a[n-1], cnt}); // for(int i = 0; i < b.size(); i++) // printf("%d %d\n", b[i].first, b[i].second); LL res = 0; for(int i = 0; i < b.size(); i++) { int t1 = b[i].first; int num1 = b[i].second; int t2 = find(t1 + c); if(t2 != -1) { res += (LL)t2 * num1; } } cout << res; return 0; }
時間複雜度
\(O(nlogn)\)