老师在黑板上写了四个数列a,b,c,d,数列a,b,c,d分别有i,j,k,l个数,突然间老师很生气的把正在睡觉的豆子喊了起来,问:“这是你第x次上课睡觉了!现在给你个赎罪的机会,你从每个数列中选择一个数,有多少种选法使他们的和为x?”,豆子实在太慌乱了,小伙伴们能告诉豆子正确答案吗?
http://acm.zzuli.edu.cn/problem.php?id=1785
老师在黑板上写了四个数列a,b,c,d,数列a,b,c,d分别有i,j,k,l个数,突然间老师很生气的把正在睡觉的豆子喊了起来,问:“这是你第x次上课睡觉了!现在给你个赎罪的机会,你从每个数列中选择一个数,有多少种选法使他们的和为x?”,豆子实在太慌乱了,小伙伴们能告诉豆子正确答案吗?
第一行有四个整数i,j,k,l(1<=i,j,k,l<=500),第二行有i个数a1,a2...ai,第三行有j个数b1,b2...bj,第四行有k个数c1,c2...ck,第五行有l个数d1,d2...dl。第六行有一个数m,接下来m行询问,每行有一个数字x。(m<=10),(|x|<10^10),(|a|,|b|,|c|,|d|<=10^8)
输出有m行,每行输出一个x对应的答案。
2 2 2 2 1 2 3 4 5 6 7 8 3 7 16 17
0 1 4
#include <iostream> #include <cstring> #include <cstdio> #include <algorithm> #include <cmath> #include <cstdlib> #include <limits> #include <queue> #include <stack> #include <vector> #include <map> using namespace std; typedef long long LL; #define N 251100 #define INF 0x3f3f3f3f #define PI acos (-1.0) #define EPS 1e-8 #define met(a, b) memset (a, b, sizeof (a)) int a1[N], b1[N], c1[N], d1[N], val1[N], val2[N]; int main () { int a, b, c, d, m, q; while (scanf ("%d %d %d %d", &a, &b, &c, &d) != EOF) { met (a1, 0), met (b1, 0), met (c1, 0), met (d1, 0); met (val1, 0), met (val2, 0); for (int i=0; i<a; i++) scanf ("%d", &a1[i]); for (int i=0; i<b; i++) scanf ("%d", &b1[i]); for (int i=0; i<c; i++) scanf ("%d", &c1[i]); for (int i=0; i<d; i++) scanf ("%d", &d1[i]); int k1 = 0, k2 = 0; for (int i=0; i<a; i++) for (int j=0; j<b; j++) val1[k1++] = a1[i] + b1[j]; for (int i=0; i<c; i++) for (int j=0; j<d; j++) val2[k2++] = c1[i] + d1[j]; scanf ("%d", &m); sort (val1, val1+k1); sort (val2, val2+k2); while (m--) { int ans = 0; scanf ("%d", &q); for (int i=0; i<k1; i++) { int v = q - val1[i]; int l = lower_bound (val2, val2+k2, v)-val2;///查找val2中>=v的元素下标 int r = upper_bound (val2, val2+k2, v)-val2;///查找val2中>v的元素下标 ans += r - l; } printf ("%d\n", ans); } } return 0; }