文章出處

4 Values whose Sum is 0
Time Limit: 15000MSMemory Limit: 228000K
Total Submissions: 19322Accepted: 5778
Case Time Limit: 5000MS

Description

The SUM problem can be formulated as follows: given four lists A, B, C, D of integer values, compute how many quadruplet (a, b, c, d ) ∈ A x B x C x D are such that a + b + c + d = 0 . In the following, we assume that all lists have the same size n .

Input

The first line of the input file contains the size of the lists n (this value can be as large as 4000). We then have n lines containing four integer values (with absolute value as large as 228 ) that belong respectively to A, B, C and D .

Output

For each input file, your program has to write the number quadruplets whose sum is zero.

Sample Input

6 -45 22 42 -16 -41 -27 56 30 -36 53 -37 77 -36 30 -75 -46 26 -38 -10 62 -32 -54 -6 45 

Sample Output

5 

Hint

Sample Explanation: Indeed, the sum of the five following quadruplets is zero: (-45, -27, 42, 30), (26, 30, -10, -46), (-32, 22, 56, -46),(-32, 30, -75, 77), (-32, -54, 56, 30).

(是不是先得翻譯 )題意大概是給定四個長度為n的數組,求四個數組各取一個元素和為0的取法有幾種(考慮順序)

 首先有兩種做法,一種二分,一種哈希

 看一眼數據規模知道枚舉每一位的O(n^4)絕對超時

 所以觀察題目,發現只要求和為0,那么考慮只枚舉出前兩個數組的任意元素和與后兩個數組任意元素和

 這樣再枚舉一遍前兩個數組的任意元素和,檢查是否有對應元素和為0即可

 接下來還要再優化

 二分寫得很簡單,具體代碼在《挑戰程序設計競賽》第23頁不想寫 

再來看哈希

把兩數組的元素和得出一個鍵值(就是哈希值)接下來鏈式儲存進去

什么叫鏈式呢?就是和鄰接表差不多

把哈希映射的數組當成head數組,把原值當成邊,存原值和next也就是哈希值相同的下一個值的為止 

注意這道題還得再優化,多存一個同一數值的重復次數而不是分開存,不然會MLE沒錯這是省空間用的

 1 #include<stdio.h>
 2 #include<stdlib.h>
 3 #include<string.h>
 4 const int mod=1000007;
 5 typedef struct{
 6         int val;
 7         int num;
 8         int next;
 9 }node;
10 int data[4005][4];
11 int n,tot=0;
12 int hash[mod+1];
13 node all[16000000];
14 int abs(int num){
15     return num>0?num:(-1)*num;//考慮負數!考慮負數!考慮負數!
16 }
17 int get(int num){
18     return (abs(num))%mod;
19 }
20 int add(int num){
21     int tmp=get(num);
22     int p=1;
23     if(hash[tmp]){
24        for(p=hash[tmp];p!=0;p=all[p].next){
25            if(all[p].val==num){
26               all[p].num++;
27               break;
28            }
29        }
30     }
31     if((!hash[tmp])||(p==0)){
32           all[++tot].val=num;
33           all[tot].num=1;
34           all[tot].next=hash[tmp];
35           hash[tmp]=tot;
36     }
37     return 0;
38 }
39 int find(int num){
40     int tmp=get(num);
41     int p;
42     for(p=hash[tmp];p;p=all[p].next){
43         if(all[p].val==num)return all[p].num;
44     }
45     return 0;
46 }
47 int main(){
48     memset(hash,0,sizeof(hash));
49     memset(all,0,sizeof(all));
50     int n;
51     scanf("%d",&n);
52     for(int i=1;i<=n;i++)scanf("%d %d %d %d",&data[i][1],&data[i][2],&data[i][3],&data[i][4]);
53     for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)add(data[i][1]+data[j][2]);
54     int ans=0;
55     for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)ans+=find(-(data[i][3]+data[j][4]));
56     printf("%d",ans);
57     return 0;

58 } 


文章列表


不含病毒。www.avast.com
全站熱搜
創作者介紹
創作者 大師兄 的頭像
大師兄

IT工程師數位筆記本

大師兄 發表在 痞客邦 留言(0) 人氣()