摘要:中途相遇。对比map,快排+二分查找,Hash效率。

n是4000的级别,直接O(n^4)肯定超,所以中途相遇法,O(n^2)的时间枚举其中两个的和,O(n^2)的时间枚举其他两个的和的相反数,然后O(logN)的时间查询是否存在。

首先试了下map,果断TLE

//TLE
#include<cstdio>
#include<algorithm>
#include<map>
using namespace std; const int maxn = ;
int data[][maxn]; map<int,int> cnt; int main()
{ int T ; scanf("%d",&T);
int *A = data[], *B = data[], *C = data[],*D = data[];
map<int,int>::iterator it;
while(T--){
int n; scanf("%d",&n);
for(int i = ; i < n; i++){
scanf("%d%d%d%d",A+i,B+i,C+i,D+i);
} for(int i = ; i < n; i++)
for(int j = ; j < n; j++){
cnt[A[i]+B[j]]++;
} int ans = ;
for(int i = ; i < n; i++)
for(int j = ; j < n; j++){
int tmp = -C[i]-D[j];
it = cnt.find(tmp);
if(it!=cnt.end()) ans += it->second;
}
printf("%d\n",ans);
if(T) putchar('\n');
} return ;
}

map,TLE

然后改成了快排+二分查找,4920ms

// runtime 4920ms
#include<cstdio>
#include<algorithm>
using namespace std; const int maxn = ;
int data[][maxn];
int vec[maxn*maxn]; int _lower_bound(int *A,int L,int R,int v)
{
int m;
while(L<R){
m = (L+R)>>;
if(A[m]>=v) R = m;
else L = m+;
}
return L;
} int _upper_bound(int *A,int L,int R,int v)
{
int m;
while(L<R){
m = (L+R)>>;
if(A[m]>v) R = m;
else L = m+;
}
return L;
} int main()
{ int T ; scanf("%d",&T);
int *A = data[], *B = data[], *C = data[],*D = data[];
while(T--){
int n; scanf("%d",&n);
for(int i = ; i < n; i++){
scanf("%d%d%d%d",A+i,B+i,C+i,D+i);
} int sz = ;
for(int i = ; i < n; i++)
for(int j = ; j < n; j++){
vec[sz++] = A[i]+B[j];
}
sort(vec,vec+sz); int ans = ;
for(int i = ; i < n; i++)
for(int j = ; j < n; j++){
int tmp = -(C[i]+D[j]);
ans += _upper_bound(vec,,sz,tmp) - _lower_bound(vec,,sz,tmp);
}
printf("%d\n",ans);
if(T) putchar('\n');
} return ;
}

快拍+二分,4920ms

实际上没有必要每次二分查找,用两个指针,两边都从最小的数开始比较。

快排+计数,2832ms

#include<cstdio>
#include<algorithm>
#include<map>
using namespace std;
typedef pair<int,int> pii;
#define fi first
#define se second
const int maxn = ;
int data[][maxn]; pii cnt1[maxn*maxn];
pii cnt2[maxn*maxn];
int vec[maxn*maxn]; int main()
{
int T ; scanf("%d",&T);
int *A = data[], *B = data[], *C = data[],*D = data[];
while(T--){
int n; scanf("%d",&n);
for(int i = ; i < n; i++){
scanf("%d%d%d%d",A+i,B+i,C+i,D+i);
}
int sz = ;
for(int i = ; i < n; i++)
for(int j = ; j < n; j++){
vec[sz++] = A[i]+B[j];
}
sort(vec,vec+sz);
int len1 = ;
cnt1[len1] = pii(vec[len1],);
for(int i = ; i < sz; i++){
if(vec[i] == cnt1[len1].fi) cnt1[len1].se++;
else { cnt1[++len1].fi = vec[i]; cnt1[len1].se = ; }
}
sz = ;
for(int i = ; i < n; i++)
for(int j = ; j < n; j++){
vec[sz++] = -C[i]-D[j];
}
sort(vec,vec+sz);
int len2 = ;
cnt2[len2] = pii(vec[len2],);
for(int i = ; i < sz; i++){
if(vec[i] == cnt2[len2].fi) cnt2[len2].se++;
else { cnt2[++len2].fi = vec[i]; cnt2[len2].se = ; }
} int p = ,q = ,ans = ;
while(p<=len1&&q<=len2){
if(cnt1[p].fi == cnt2[q].fi){
ans += cnt1[p++].se*cnt2[q++].se;
}else if(cnt1[p].fi>cnt2[q].fi) q++;
else p++;
}
printf("%d\n",ans);
if(T) putchar('\n');
} return ;
}

快排+计数

还有Hash表,写挂了,待补。。。

UVA 1152 4 Values Whose Sum is Zero 和为0的4个值 (中途相遇)的更多相关文章

  1. 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< ...

  2. uva 1152 4 values whose sum is zero ——yhx

    The SUM problem can be formulated as follows: given four lists A;B;C;D of integer values, computehow ...

  3. UVa 1152 -4 Values whose Sum is 0—[哈希表实现]

    The SUM problem can be formulated as follows: given four lists A, B, C, D of integer values, compute ...

  4. UVA - 1152 4 Values whose Sum is 0(中途相遇法)

    题意:从四个集合各选一个数,使和等于0,问有多少种选法. 分析:求出来所有ai + bi,在里面找所有等于ci + di的个数. #pragma comment(linker, "/STAC ...

  5. UVa 1152 4 Values whose Sum is 0

    题意:给出n,四个集合a,b,c,d每个集合分别有n个数,分别从a,b,c,d中选取一个数相加,问使得a+b+c+d=0的选法有多少种 看的紫书,先试着用hash写了一下, 是用hash[]记录下来a ...

  6. UVA - 1152 4 Values whose Sum is 0问题分解,二分查找

    题目:点击打开题目链接 思路:暴力循环显然会超时,根据紫书提示,采取问题分解的方法,分成A+B与C+D,然后采取二分查找,复杂度降为O(n2logn) AC代码: #include <bits/ ...

  7. UVA - 1152 --- 4 Values whose Sum is 0(二分)

    问题分析 首先枚举a和b, 把所有a+b记录下来放在一个有序数组,然后枚举c和d, 在有序数组中查一查-c-d共有多少个.注意这里不可以直接用二分算法的那个模板,因为那个模板只能查找是否有某个数,一旦 ...

  8. 8-3 4Values Whose Sum is Zero 和为0的四个值

    给定四个n元素集合 ABCD   要求分别从中取一个元素 abcd   使得他们的合为0   问有多少中取法 map果然炸了 #include<bits/stdc++.h> using n ...

  9. 【uva 1152】4 Values Whose Sum is Zero(算法效率--中途相遇法+Hash或STL库)

    题意:给定4个N元素几个A,B,C,D,要求分别从中选取一个元素a,b,c,d使得a+b+c+d=0.问有多少种选法.(N≤4000,D≤2^28) 解法:首先我们从最直接最暴力的方法开始思考:四重循 ...

随机推荐

  1. js中match的用法

    match() 方法将检索字符串 stringObject,以找到一个或多个与 regexp 匹配的文本.这个方法的行为在很大程度上有赖于 regexp 是否具有标志 g. 一.如果 regexp 没 ...

  2. CSS实现三角形图标原理解析

    CSS实现三角形图标原理解析: border边框语法: border 四条边框设置border-left 设置左边框,一般单独设置左边框样式使用border-right 设置右边框,一般单独设置右边框 ...

  3. 安装VMware-tools出现initctl: Job failed to start

    安装VMware-tools中出现: ******* Creating a new initrd boot image for the kernel.update-initramfs: Generat ...

  4. poj2528(线段树区间替换&离散化)

    题目链接: http://poj.org/problem?id=2528 题意: 第一行输入一个 t 表 t 组输入, 对于每组输入: 第一行  n 表接下来有 n 行形如 l, r 的输入, 表在区 ...

  5. vue+element-ui实现无限级动态菜单树

    使用vue+element-ui实现无限级动态菜单 该案例实现主要使用递归的思想,递归对新人来容易迷惑的是自己调用自己,直到满足条件为止,接下来我们就一步一步实现一个动态多级菜单vue组件 搭建项目并 ...

  6. Ajax案例:异步加载后台订单详情信息

  7. css3椭圆运动

    通过使用css3实现让元素椭圆运动.而不是圆形运动. 效果1:http://sandbox.runjs.cn/show/ignefell 效果2:http://runjs.cn/code/w2wxjy ...

  8. 原型设计模式(prototype

    # 什么是原型设计模式 > 这里与软件工程中的原型开发模式有那么一点类似的地方,我们首先需要构建出一个原型,这个原型可以在现实开发中抽象出来的具体类型,但是这个类型与具体的类又不同,需要抽取公共 ...

  9. NET Core 2.0 自定义

    ASP.NET Core 2.0 自定义 _ViewStart 和 _ViewImports 的目录位置 在 ASP.NET Core 里扩展 Razor 查找视图目录不是什么新鲜和困难的事情,但 _ ...

  10. 应用的入口——Startup

    应用的入口——Startup 一个ASP.NET Core应用被启动之后就具有了针对请求的处理能力,而这个能力是由管道赋予的,所以应用的启动同时意味着管道的成功构建.由于管道是由注册的服务器和若干中间 ...