摘要:中途相遇。对比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. 315. Count of Smaller Numbers After Self(Fenwick Tree)

    You are given an integer array nums and you have to return a new counts array. The counts array has ...

  2. laravel ajax提交登陆存储session,并输出

    前端输出session {{ Session::get('username') }} ajax提交 <div>{{ Session::get('username') }}</div& ...

  3. unity coroutine

    http://gad.qq.com/article/detail/695 使用Unity 3D引擎的同学,对于Coroutine(协程)的使用肯定也是非常熟悉的了.然而Coroutine背后的技术以及 ...

  4. 2014 Noip提高组 Day2

    P2038 无线网络发射器选址 [题目描述] 随着智能手机的日益普及,人们对无线网的需求日益增大.某城市决定对城市内的公共场所覆盖无线网. 假设该城市的布局为由严格平行的129 条东西向街道和129 ...

  5. Candies

    Candies Time Limit: 1500MS   Memory Limit: 131072K Total Submissions: 30247   Accepted: 8409 Descrip ...

  6. 洛谷P2292 [HNOI2004]L语言

    传送门 建好trie树 当$dp[j]==1$当且仅当存在$dp[k]=1$且$T[k+1,j]==word[i]$ 然后乱搞就行了 //minamoto #include<iostream&g ...

  7. [Xcode 实际操作]七、文件与数据-(9)编码创建Plist文件(属性列表文件)

    目录:[Swift]Xcode实际操作 本文将演示如何通过编码的方式,创建属性列表文件. 在项目导航区,打开视图控制器的代码文件[ViewController.swift] import UIKit ...

  8. 记录错误:tomcat“socket close”错误

    Error running 'Tomcat 8.5.37': Unable to open debugger port (127.0.0.1:9562) 使用打开cmd.exe 输入 1)taskli ...

  9. Mac中文输入法无选字框了?

    按F4键,把其它中的活动监视器打开,选简体中文输入法进程,双击点退出 ,再点强制退出,关了吧.再打字,好用了-

  10. day7计算作业详解

    1.day7题目 1.判断一个数是否是水仙花数, 水仙花数是一个三位数, 三位数的每一位的三次方的和还等于这个数. 那这个数就是一个水仙花数, 例如: 153 = 13 + 53 + 3**3 2.给 ...