• [poj2785]4 Values whose Sum is 0(hash或二分)


    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 } 

  • 相关阅读:
    linux-01-04(创建文件夹mkdir,进入目录命令cd,创建文件命令 echo cp vim touch等,批量创建文件操作)
    linux-05(tar命令的使用)
    linux-06(移动命令mv)
    linux-07(复制命令cp)
    linux-08(查看命令历史记录history)
    cookie
    vue-router路由懒加载
    setTimeout async promise执行顺序总结
    forEach陷阱
    函数节流与函数防抖之间的区别
  • 原文地址:https://www.cnblogs.com/Pumbit-Legion/p/5574572.html
Copyright © 2020-2023  润新知