1. 程式人生 > 資訊 >優必選釋出仿人服務機器人 Walker X,可上樓梯、下斜坡、下象棋、柔順力控按摩

優必選釋出仿人服務機器人 Walker X,可上樓梯、下斜坡、下象棋、柔順力控按摩

題目描述

出題是一件痛苦的事情!

相同的題目看多了也會有審美疲勞,於是我捨棄了大家所熟悉的 A+B Problem,改用 A-B 了哈哈!

好吧,題目是這樣的:給出一串數以及一個數字C,要求計算出所有A - B = C的數對的個數(不同位置的數字一樣的數對算不同的數對)。

輸入格式

輸入共兩行。

第一行,兩個整數N, C。

第二行,N個整數,作為要求處理的那串數。

輸出格式

一行,表示該串數中包含的滿足A - B = C的數對的個數。

輸入輸出樣例

輸入#1

輸出#1

4 1

1 1 2 3

3

說明/提示

對於75%的資料,1≤N≤2000。

對於100%的資料,1≤N

≤2e5。

保證所有輸入資料絕對值小於2^30。

2017/4/29 新添資料兩組

  題目分析

  1. 資料規模N最大為2e5,普通查詢方式肯定會超時,我們可以先對序列排序,然後用二分查詢查詢資料。
  2. A – B = C可知,A、B是變數C是常量,那麼我們知道A就可以通過C求B,轉化式子為:A – C = B。
  3. A是輸入資料中的序列,C是具體數,B是A – C的結果。通過A – C得到的B作為key(要查詢的關鍵詞),在原序列中去尋找是否存在。
  4. 遍歷時每次判斷得到B是否存在,用一個計數器來記錄存在次數,遍歷完序列後輸出。
  5. 關鍵的小坑:待查的B結果可能不止一個,所以查詢還得查出B在序列中有幾個。此處可以用下面陳述的程式碼,有空用C++中STL裡的函式upper_bound()和lower_bound函式來確定左右邊界,差值即為B的個數(
    函式快捷入口
    )。

可行程式碼

#include <algorithm>
#include <iostream>
using namespace std;

int search(int key, int *arr, int len) {
    int l = -1, r = len - 1, mid; // 注意的是陣列是從0開始的
    while (l + 1 < r) {
        mid = l + r >> 1;
        if (arr[mid] <= key)
            l = mid;
        
else r = mid; } return r; // 返回第一個大於key的位置 } int main() { int NumCount, AimNum; // 序列長度、C的值 cin >> NumCount >> AimNum; int num[NumCount]; for (int i = 0; i < NumCount; i++) cin >> num[i]; long long Sum = 0; // 資料很大 sort(num, num + NumCount); // 二分查詢的前提是序列有序 for (int i = 0; i < NumCount; i++) { int begin = search(num[i] - AimNum - 1, num, i + 1); // 左邊界 int end = search(num[i] - AimNum, num, i + 1); // 右邊界 Sum += end - begin; // 每次查詢結果疊加 } cout << Sum << endl; return 0; }

END感謝reader's閱讀,洛谷題目連結:P1102 A-B 數對 - 洛谷 | 電腦科學教育新生態 (luogu.com.cn)