题意:
There are 5 Integer Arrays and each of them contains no more than 300 integers whose value are between -100,000,000 and 100,000,000, You are to find how many such groups (i,j,k,l,m) can make A[0][i]+A[1][j]+A[2][k]+A[3][l]+A[4][m]=0.
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<map>
#define M 305
using namespace std;
int s[3][M*M];
int cnt[3][M*M];
int A[5][M], num[5], B[M*M], fnum[4];
bool cmp(int a, int b) {
return a > b;
}
void get(int w, int k, int B[]) {
int i, j;
for (j = i = 0; i < w; i++)cnt[k][i] = 0;
s[k][0] = B[0];
cnt[k][0]++;
for (i = 1; i < w; i++) {
if (B[i] != s[k][j]) s[k][++j] = B[i];
cnt[k][j]++;
}
fnum[k] = j + 1;
}
int main() {
int cas, i, j, ans, w;
scanf("%d", &cas);
while (cas--) {
for (i = 0; i < 5; i++) for (scanf("%d", &num[i]), j = 0; j < num[i]; j++) scanf("%d", &A[i][j]);
sort(A[4], A[4] + num[4], cmp);
get(num[4], 0, A[4]);
for (w = i = 0; i < num[0]; i++) for (j = 0; j < num[1]; j++) B[w++] = A[0][i] + A[1][j];
sort(B, B + w, cmp);
get(w, 1, B);
for (w = i = 0; i < num[2]; i++) for (j = 0; j < num[3]; j++) B[w++] = A[2][i] + A[3][j];
sort(B, B + w);
get(w, 2, B);
int pos = 0, tmp = 0, xx;
for (ans = i = 0; i < fnum[0]; i++) {
xx = s[0][i] + s[1][0];
while (tmp < fnum[2] && xx + s[2][tmp] < 0)tmp++;
if (tmp == fnum[2])break;
if (xx + s[2][tmp] == 0) ans += cnt[0][i] * cnt[1][0] * cnt[2][tmp];
pos = tmp;
for (j = 1; j < fnum[1]; j++) {
xx = s[0][i] + s[1][j];
while (pos < fnum[2] && xx + s[2][pos] < 0)pos++;
if (pos == fnum[2])break;
if (xx + s[2][pos] == 0) ans += cnt[0][i] * cnt[1][j] * cnt[2][pos];
}
}
printf("%d\n", ans);
}
return 0;
}
这题复杂度为O(n(n*n+n*n)),居然在hdu最快。一开始写了个n^3logn(如果map的复杂度是logn)的TLE。
接下来就想出和上面差不多的代码,不过for的次序不一样所以n*n(n+n*n)。此题的优化以后可以借鉴。