zoukankan      html  css  js  c++  java
  • UVA 1152 4 Values whose Sum is 0 (枚举+中途相遇法)(+Java版)(Java手撕快排+二分)

    4 Values whose Sum is 0

     题目链接:https://cn.vjudge.net/problem/UVA-1152

        ——每天在线,欢迎留言谈论。

    题目大意:

       给定4个n(1<=n<=4000)元素的集合 A、B、C、D ,从4个集合中分别选取一个元素a, b,c,d。求满足 a+b+c+d=0的对数。

    思路:

      直接分别枚举 a,b,c,d ,坑定炸了。我们先枚举 a+b并储存,在B、C中枚举找出(-c-d)后进行比较即可。

    亮点:

      由于a+b,中会有值相等的不同组合,如果使用map来存,很遗憾超时(虽然时间限制是9000ms)。

      在一个有序数组求某元素数出现的个数:n = upper_bound(a,a+n,k)-lower_bound(a,a+n,k) ;

    C++ AC代码:

     1 #include <iostream>
     2 #include <cmath>
     3 #include <iostream>
     4 #include <string>
     5 #include <string.h>
     6 #include <cstdio>
     7 #include <algorithm>
     8 #include <map>
     9 using namespace std;
    10 const int INT_INF = 0x3f3f3f3f;
    11 const double EPS = 1e-7;
    12 typedef long long ll;
    13 const int MAXN = 4e3+100;
    14 int numbers[4][MAXN],sumAB[MAXN*MAXN];
    15 int main()
    16 {
    17     int t;
    18     cin>>t;
    19     while(t--)
    20     {
    21         memset(numbers,0,sizeof(numbers));
    22         memset(sumAB,INT_INF,sizeof(sumAB));
    23         int n,p1=0,p2=0;
    24         cin>>n;
    25         for(int i=0;i<n;i++)
    26             for(int j=0;j<4;j++)
    27                 cin>>numbers[j][i];
    28         for(int i=0;i<n;i++)
    29             for(int j=0;j<n;j++)
    30             sumAB[p1++]=numbers[0][i]+numbers[1][j];
    31         sort(sumAB,sumAB+p1);
    32         int answer=0;
    33         for(int i=0;i<n;i++)
    34             for(int j=0;j<n;j++)
    35         {
    36             answer+=upper_bound(sumAB,sumAB+p1,-numbers[2][i]-numbers[3][j])-lower_bound(sumAB,sumAB+p1,-numbers[2][i]-numbers[3][j]);
    37         }
    38         cout<<answer<<endl;
    39         if(t)
    40             cout<<endl;
    41     }
    42     return 0;
    43 }

    Java AC代码:

     1 import java.util.Scanner;
     2 public class Main {
     3     static Scanner scn = new Scanner(System.in);
     4     
     5     static final int MAXN = 4100;
     6     static int[][] numbers = new int[4][MAXN];
     7     static int[] sumAB = new int[MAXN*MAXN];
     8     public static void main(String[] args) {
     9         int t;   
    10         t = scn.nextInt();
    11         while ((t--) > 0) {
    12             int n;
    13             n = scn.nextInt();
    14             for (int i = 0; i < n; i++) {
    15                 for (int j = 0; j < 4; j++) {
    16                     numbers[j][i] = scn.nextInt();
    17                 }
    18             }
    19             int p1 = 0;
    20             for (int i = 0; i < n; i++) {
    21                 for (int j = 0; j < n; j++) {
    22                     sumAB[p1++] = numbers[0][i] + numbers[1][j];
    23                 }
    24             }
    25             Tool.quickSort(sumAB,0,p1-1);
    26             //输出看看
    27 //            for (int i = 0; i < p1; i++) {
    28 //                System.out.print(sumAB[i] + " ");
    29 //            } //成功
    30             //开始枚举-c-d
    31             int answer = 0;
    32             for (int i = 0; i < n; i++) {
    33                 for (int j = 0; j < n; j++) {
    34                     answer += Tool.uppper(sumAB, 0, p1, -numbers[2][i] - numbers[3][j]) - Tool.lower(sumAB, 0, p1, -numbers[2][i] - numbers[3][j]);
    35                 }
    36             }
    37             System.out.println(answer);
    38             if(t > 0)
    39                 System.out.println();
    40         }
    41         System.exit(0);
    42     }
    43 }
    44 class Tool {
    45     public static int lower(int[] array, int low, int high, int number) {
    46         //[low,high)
    47         int i = low, j = high, m;
    48         while (i < j) {
    49             m = i + (j - i) / 2;
    50             if (array[m] >= number)
    51                 j = m;
    52             else 
    53                 i = m+1;
    54         }
    55         return i;
    56     }
    57     public static int uppper(int[] array, int low, int high, int number) {
    58         int i = low, j = high, m;
    59         while (i < j) {
    60             m = i + (j - i) / 2;
    61             if (array[m] <= number)
    62                 i = m+1;
    63             else
    64                 j = m;
    65         }
    66         return i;
    67     }
    68     public static void quickSort(int[] array, int low, int high) {
    69         if (low < high) {
    70             int m = partition(array, low, high);
    71             quickSort(array, low, m-1);
    72             quickSort(array, m+1, high);
    73         }
    74     }
    75     private static int partition(int[] array, int low, int high) {
    76         int mNumber = array[low];
    77         int i = low, j = high;
    78         while (i < j) {
    79             while (i < j && array[j] >= mNumber) {--j;}
    80             array[i] = array[j];
    81             while (i < j && array[i] <= mNumber) {++i;}
    82             array[j] = array[i];
    83         }
    84         array[i] = mNumber;
    85         return i;
    86     }
    87 }

    2017-07-30 11:06:43 -> 2017-07-30 13:45:32

  • 相关阅读:
    HDU 1800 Flying to the Mars 字典树,STL中的map ,哈希树
    字典树 HDU 1075 What Are You Talking About
    字典树 HDU 1251 统计难题
    最小生成树prim算法 POJ2031
    POJ 1287 Networking 最小生成树
    次小生成树 POJ 2728
    最短路N题Tram SPFA
    poj2236 并查集
    POJ 1611并查集
    Number Sequence
  • 原文地址:https://www.cnblogs.com/Twobox/p/7258560.html
Copyright © 2011-2022 走看看