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