1. 程式人生 > 實用技巧 >A-B數對 (hash對映)

A-B數對 (hash對映)

題目大意:

第一行輸入N,C
第二行輸入n個數字
輸出,求A - B = C的數對個數

樣例

4 1
1 1 2 3

輸出

3

思路:用STL容器map,map<num, times>,建立一個數字出現的次數的對映,題目要求是A - B = C,我們將其轉換成A - C = B,並且將a陣列依次減去C,最後再將A掃描一遍,將所有對映的次數加起來就是結果res

程式碼

#include <map>
#include <cstdio>
#include <iostream>

using namespace std;

const int N = 200010;
typedef long long LL;
LL a[N];
map<LL, LL> mp;

int main()
{
    int n;
    LL res = 0, c;

    scanf("%d%d", &n, &c);
    for(int i = 1; i <= n; i++)
    {
        scanf("%d", &a[i]);
        mp[a[i]]++;
        a[i] -= c;
    }

    for(int i = 1; i <= n; i++) res += mp[a[i]];

    printf("%d", res);
    system("pause");
    return 0;
}

這個思路很巧妙,原理想了很久~但是理解的還不是很透徹,個人理解:假設a陣列中減去數之後變為b陣列,那麼若想要原陣列a中的產生A - B = C數對,那麼b陣列中的數也一定存在於原來的a陣列,因此可以直接遍歷a陣列進行計數

按照題給樣例
為了更好理解 a[]陣列挨個減去C之後變成b[]陣列
a[1] = 1; C = 1 那麼a[]陣列中還需要一個元素 0 才能與 1 構成數對,但是 0 並不存在,因此b[1] = 0,即mp[0] = 0;
a[2] = 1; C = 1 同理b[2] = 0,mp[0] = 0.
a[3] = 2; C = 1 那麼a[]陣列中需要一個 1 才能與 2 構成數對,剛好 1 有兩個,b[3] = 1

,即mp[1] = 2;
a[4] = 3; C = 1 那麼a[]陣列需要一個 2 才能與 3 構成數對, 剛好 2 有一個,b[4] = 2,即mp[2] = 1;
因此res = mp[0] + mp[0] + mp[1] + mp[2] = 3