標籤:
Thinking about it:
看到這題時,我馬上想到了hdu 的 1496,這兩題有異曲同工之處。我個人對hdu1496的題解:Click Here
將所有第一第二個數的和a + b都儲存起來,記錄每個數出現的次數,然後計算每一個c + d,對於每一個c + d,查詢-(c + d)出現幾次就可。
因此本題需要有一種方法儲存將所有a + b的和及其出現次數儲存起來。
最直接的方法,就是使用STL中的map,但map在這種資料量較大時容易逾時,所以這種方法在這裡並不理想。
另一種方法就是自己建立一個雜湊表,因為和可能是負數,所以可以加上OFFSET,使所有和加上OFFSET的值都大於0,並且這個值作為key。而雜湊表則可以採用一個vector數組表示。
PS:
相比我自己以前在hdu1496的做法,這次我很自然的想到了用vector表示雜湊數組,方便了很多。一般來說,自己想到的方法應該更容易留下深刻的印象。
Reference:
0.http://acm.lilingfei.com/71_71
Code:
/** * AC @ Sep 2nd 2015 */#include <bits/stdc++.h>using namespace std;typedef long long LL;const int MAXN = 4000 + 50;const int hashsize = 999983; // 149993 -> 2.528s 299993 -> 2.205s 999983 -> 2.658const int OFFSET = 1 << 30;struct Node{ int value; LL cnt; Node(int v, LL c){ value = v; cnt = c; } Node(){}};int lst[MAXN][5], N;std::vector<Node> table[hashsize];void init() { for(int i=0; i<hashsize; ++ i) { table[i].clear(); }}void read() { cin >> N; for(int i=0; i<N; ++ i) { for(int j=0; j<4; ++ j) { cin >> lst[i][j]; } }}void insert(int sum) { int value = sum % hashsize; for (std::vector<Node>::iterator it = table[value].begin(); it != table[value].end(); ++it) { if (it->value==sum) { ++ it->cnt; return ; } } table[value].push_back(Node(sum, 1));}LL find(int sum) { int value = sum % hashsize; for (std::vector<Node>::iterator it = table[value].begin(); it != table[value].end(); ++it) { if(it->value == sum) { return it->cnt; } } return 0;}void work() { init(); int sum; for(int i=0; i<N; ++ i) { for(int j=0; j<N; j++) { sum = lst[i][0] + lst[j][1]; insert(sum + OFFSET); } } long long ans = 0; for(int i=0; i<N; ++ i) { for(int j=0; j<N; j++) { sum = lst[i][2] + lst[j][3]; ans = ans + find(-sum + OFFSET); } } cout << ans << endl;}int main() { ios::sync_with_stdio(false); cin.tie(0); int T; cin >> T; while(T --) { read(); work(); if(T) { cout << endl; } } return 0;}
uva 1152 4 Values whose Sum is 0