題目描述
小明一共有n塊鍛造石,第塊鍛造石的屬性值為ai.
現在小明決定從這n塊鍛造石中任取兩塊來鍛造兵器
通過周密計算,小明得出,只有當兩塊鍛造石的屬性值的差值等于C,兵器才能鍛造成功
請你幫小明算算,他有多少種選取鍛造石的方案可以使得鍛造成功
輸入描述
第一行包含兩個整數n,C,其含義如題所述
接下來一行包含n個整數,分別表示a1,a2,··,an.
1 < N < 2 x 10^5,|ai| < 10^4,0 < C < 10^9
輸出描述
輸出共一行,包含一個整數,表示答案.
輸入輸出樣例
6 3
8 4 5 7 7 4
?5
解題思路
這個題是一道典型的雙指針題,要控制快指針和慢指針所對應的數據之差為C。
首先,使用排序方法對輸入數據進行排序是必要的。
然后快指針優先移動,直到快慢指針數據之差至少為C;接下來慢指針進行移動,如果不是C(就一定比C大)就往后移動,直到快慢指針之差至多為C。
到此就是一組快慢指針的移動,此時可以判斷快慢指針數據之差是否為C,如果是,就對ans做更新。這題的關鍵是ans更新多少,我們思考后不難發現,按照題目提供的例子,兩個7的石頭可以與兩個4的石頭分別組成一組,這意味著組合數量是滿足要求的兩個數值的石頭的個數乘積,那么我們只需要對快慢指針分別派生出一個新指針,分別向后步進進行計數即可。
下面給出代碼:
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.reflect.Array;
import java.math.BigInteger;
import java.util.*;public class Main {public static void main(String[] args) throws IOException {Scanner sc = new Scanner(System.in);BufferedReader in = new BufferedReader(new InputStreamReader(System.in));String[] temp = in.readLine().split(" ");int n = Integer.parseInt(temp[0]);int c = Integer.parseInt(temp[1]);temp = in.readLine().split(" ");int[] data = new int[n];for (int i = 0; i < n; i++) {data[i] = Integer.parseInt(temp[i]);}Arrays.sort(data);int slow = 0, fast = 0;long ans = 0;while (fast < n) {while (fast < n && data[fast] - data[slow] < c) {fast++;}while (fast < n && data[fast] - data[slow] > c) {slow++;}if (fast < n && data[fast] - data[slow] == c) {int oldFast = fast, oldSlow = slow;while (fast < n && data[fast] == data[oldFast]) {fast++;}while (slow < n && data[slow] == data[oldSlow]) {slow++;}ans += (long) (fast - oldFast) * (slow - oldSlow);}}System.out.println(ans);}
}