1046. 4个值的和为0

kingno

折半枚举

#include<cstdio>
#include<algorithm>
using namespace std;

const int maxn=4000;
int n;
int A[maxn],B[maxn],C[maxn],D[maxn];
int CD[maxn*maxn];

void solve() {
    for(int i=0; i<n; ++i)
        for(int j=0; j<n; ++j)
            CD[i*n+j]=C[i]+D[j];
    sort(CD,CD+n*n);

    long long ans=0;
    for(int i=0; i<n; ++i) {
        for(int j=0; j<n; ++j) {
            int cd=-A[i]-B[j];
            ans += upper_bound(CD, CD+n*n, cd) - lower_bound(CD, CD+n*n, cd);
        }
    }
    printf("%lld\n",ans);
}

int main() {
    scanf("%d",&n);
    for(int i=0; i<n; ++i) {
        scanf("%d%d%d%d",&A[i],&B[i],&C[i],&D[i]);
    }
    solve();
    return 0;
}
10152130220

卡STL,老实手写吧
[em:14]

帕秋莉_诺蕾姬

此题用二分的话速度非常慢,这里用哈希表写,不知道的同学可以百度一下,一种以常数时间插入和查找的数据结构

#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#define HASHSIZE 19999999//19999999是一个素数
#define N 4005
#define MAX (1<<29) //绝对值小于2^28则用一个大数MAX来保护下标
typedef long l;
typedef struct Hash {
    l key, size;//关键字和出现的次数
    struct Hash*next;
}hash;//用拉链法解决冲突,这里才用linked-list,我看了别人的答案有用数组实现的好像更快??
hash*hashing[HASHSIZE];//hash表
l a[N], b[N], c[N], d[N], n, ans;
hash*findhash(l n)
{
    l a = n % HASHSIZE;
    hash*p = hashing[a];
    while (p)//查找链表用平衡树更快不过这个代码量。。。
        if (p->key == n)
            return p;
        else
            p = p->next;
    return NULL;
}
hash*newhash(l n)//建立新节点
{
    hash*node = (hash*)malloc(sizeof(hash));
    node->key = n; node->size = 1;
    node->next = NULL;
    return node;
}
void addhash(l n)
{
    hash*p = findhash(n); int a = n % HASHSIZE;//采用直接取余法,优点:
    if (p)//假如出现过
        p->size++;//次数加一
    else
    {//没出现过,创建新节点 插入链表头部
        hash*pnode = hashing[a];
        hashing[a] = newhash(n);
        hashing[a]->next = pnode;
    }
}
int main()
{
    scanf("%ld", &n);
    for (l i = 1; i <= n; i++)
        scanf("%ld%ld%ld%ld", &a[i], &b[i], &c[i], &d[i]);
    for (l i = 1; i <= n; i++)
        for (l j = 1; j <= n; j++)
            addhash(MAX + a[i] + b[j]);
    for (l i = 1; i <= n; i++)
        for (l j = 1; j <= n; j++)
        {
            hash*p = findhash(MAX - c[i] - d[j]);
            if (p)//假如出现过
                ans += p->size;//加上出现的次数
        }
    printf("%ld\n", ans);
}
你当前正在回复 博客/题目
存在问题!