(暴力+优化)学渣的逆袭 -- zzuli -- 1785

http://acm.zzuli.edu.cn/problem.php?id=1785

学渣的逆袭

Time Limit: 3 Sec  Memory Limit: 128 MB
Submit: 82  Solved: 21

SubmitStatusWeb Board

Description

 老师在黑板上写了四个数列a,b,c,d,数列a,b,c,d分别有i,j,k,l个数,突然间老师很生气的把正在睡觉的豆子喊了起来,问:“这是你第x次上课睡觉了!现在给你个赎罪的机会,你从每个数列中选择一个数,有多少种选法使他们的和为x?”,豆子实在太慌乱了,小伙伴们能告诉豆子正确答案吗?

Input

 第一行有四个整数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)

Output

 输出有m行,每行输出一个x对应的答案。

Sample Input

2 2 2 2
1 2
3 4
5 6
7 8
3
7
16
17

Sample Output

0
1
4
 
代码很容易看懂, 因为就是一个暴力的题, 加了些优化, 但时间快了不少, 优化的力量是强大的呀,可惜我却不怎么懂优化, 慢慢学吧!!!
 
 
 
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<algorithm>
using namespace std;

const int N = 510;

int a[N], b[N], c[N], d[N];
int v1[N*N], v2[N*N];

int main()
{
    int A, B, C, D;

    while(scanf("%d%d%d%d", &A, &B, &C, &D)!=EOF)
    {
        int i, j, ans1=0, ans2=0, m, x;

        for(i=0; i<A; i++) scanf("%d", &a[i]);
        for(i=0; i<B; i++) scanf("%d", &b[i]);
        for(i=0; i<C; i++) scanf("%d", &c[i]);
        for(i=0; i<D; i++) scanf("%d", &d[i]);

        for(i=0; i<A; i++)
        for(j=0; j<B; j++)
            v1[ans1++] = a[i] + b[j];
        for(i=0; i<C; i++)
        for(j=0; j<D; j++)
            v2[ans2++] = c[i] + d[j];

        sort(v1, v1+ans1);
        sort(v2, v2+ans2);

        scanf("%d", &m);

        while(m--)
        {
            long long sum=0;
            scanf("%d", &x);

            for(i=0; i<ans1; i++)
            {
                int w = x - v1[i];
                int l, r;
                if(binary_search(v2, v2+ans2, w))
                {
                    l = lower_bound(v2, v2+ans2, w) - v2;
                    r = upper_bound(v2, v2+ans2, w) - v2;
                    sum += r-l;
                }
            }
            printf("%lld
", sum);
        }
    }
    return 0;
}
#include<cstdio>
#include<cstring>
#include<stack>
#include<vector>
#include<queue>
#include<cmath>
#include<cstdlib>
#include<algorithm>
using namespace std;
const int oo = 0x3f3f3f3f;
const int maxn = 1e4+7;
const int mod = 998244353;
typedef long long LL;
int a[maxn], b[maxn], c[maxn], d[maxn];
LL ans;
void init(int &m, int o[], int n, int val)
{
    m = lower_bound(o, o+n, val)-o;
    if(o[m] > val || m == n) m--;
}
int main()
{
    int i, j, q, w, e, r, m, x, k;
    int z, s, v;
    while(~scanf("%d %d %d %d", &q, &w, &e, &r))
    {
        for(i = 0; i < q; i ++) scanf("%d", &a[i]);
        for(i = 0; i < w; i++)scanf("%d", &b[i]);
        for(i = 0; i < e; i++) scanf("%d", &c[i]);
        for(i = 0; i < r; i++)scanf("%d", &d[i]);
        sort(a, a+q); sort(b, b+w);
        sort(c, c+e); sort(d, d+r);
        scanf("%d", &m);
        while(m--)
        {
            scanf("%d", &x);
            ans = 0;
           init(z, a, q, x); init(s, b, w, x); init(v, c, e, x);
            for(i = 0; i <= z; i ++)
            {
                if(a[i] > x) break;
                for(j = 0; j <= s; j ++)
                {
                    if(a[i]+b[j] > x) break;
                    for(k = 0; k <= v; k++)
                    {
                        if(a[i]+b[j]+c[k] > x) break;
                        int v = x-a[i]-b[j]-c[k];
                        if(binary_search(d, d+r, v))ans++;
                    }
                }
            }
            printf("%lld
", ans);
        }
    }
    return 0;
}
  
/**************************************************************
    Problem: 1785
    User: 2759894160
    Language: C++
    Result: Accepted
    Time:1667 ms
    Memory:1032 kb
****************************************************************/
 
 
勿忘初心
原文地址:https://www.cnblogs.com/YY56/p/4994880.html