摘要:中途相遇。对比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. 自定义TabWidget

    在开发过程中,默认的TabWidget不能满足我们对于UI的要求并且没有足够的属性工我们去修改,这个时候能够自定义TabWidget是非常必要的.自定义TabWidget组要运用的是TabSpec.s ...

  2. 安装coreseek 编译错误

    Ubuntu下 编译csft 报错fatal error python.h no such file or directory 执行apt-get install python-dev即可

  3. JavaScript巩固篇(一)——数据类型与全局变量、局部变量、垃圾回收机制、存储方式、生命周期

    知识要点 数据类型 存储方式 全局变量与局部变量 变量的生命周期 垃圾回收机制 知识概览 数据类型 JavaScript的数据类型分为:基本类型.引用类型 本质区别: 基本数据类型的变量实际值存储在栈 ...

  4. nodejs ejs 引擎脱离express使用

    之前用ejs都是使用express创建项目,然后在app.js中配置好的ejs直接使用即可,但是最近项目中使用的手工路由模式,脱离了express,不知道怎么用了,去扒ejs的网站,各种资料,也是懵懵 ...

  5. 关于fiddler抓取HTTPS请求443的问题

    1.环境:fiddler4.IOS10.3以上 2.需求:使用fiddler抓取IOS上的https请求 3.解决方案 步骤一:设置fiddler 步骤二:手机端安装证书 手机设置代理,打开手机浏览器 ...

  6. atom 插件 python语法验证linter-flake8-------填坑

    python的语法相对于一般语言的语法比较严格.对于刚刚从前端入门python的我来说,有时候代码写完了,然后报错,好多语法错误.所以这个时候一个好的语法验证插件是很好的.linter-flake8这 ...

  7. CC38:第k个数

    题目 有一些数的素因子只有3.5.7,请设计一个算法,找出其中的第k个数. 给定一个数int k,请返回第k个数.保证k小于等于100. 测试样例: 3 返回:7 解法 主要就是在于isPrime这个 ...

  8. 1.检索数据 ---SQL

    相关提示: 结束SQL语句 多条SQL语句必须以分号(:)分隔.多数DBMS不需要在单条SQL语句后加分号,但也有DBMS可能必须在单条SQL语句后加上分号.当然,如果愿意可以总是加上分号.事实上,即 ...

  9. [Leetcode]003. Longest Substring Without Repeating Characters

    https://leetcode.com/problems/longest-substring-without-repeating-characters/ public class Solution ...

  10. Xshell连接不上虚拟机&连接提示SSH服务器拒绝了密码,请再试一次

    问题1:Xshell连接不上虚拟机 #启动ssh服务 /etc/init.d/ssh start #查看SSH服务22端口是否开启 netstat -antulp | grep ssh 问题2:XSh ...