UVA 1152 4 Values Whose Sum is Zero 和为0的4个值 (中途相遇)
摘要:中途相遇。对比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个值 (中途相遇)的更多相关文章
- 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< ...
- 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 ...
- 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 ...
- UVA - 1152 4 Values whose Sum is 0(中途相遇法)
题意:从四个集合各选一个数,使和等于0,问有多少种选法. 分析:求出来所有ai + bi,在里面找所有等于ci + di的个数. #pragma comment(linker, "/STAC ...
- 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 ...
- UVA - 1152 4 Values whose Sum is 0问题分解,二分查找
题目:点击打开题目链接 思路:暴力循环显然会超时,根据紫书提示,采取问题分解的方法,分成A+B与C+D,然后采取二分查找,复杂度降为O(n2logn) AC代码: #include <bits/ ...
- UVA - 1152 --- 4 Values whose Sum is 0(二分)
问题分析 首先枚举a和b, 把所有a+b记录下来放在一个有序数组,然后枚举c和d, 在有序数组中查一查-c-d共有多少个.注意这里不可以直接用二分算法的那个模板,因为那个模板只能查找是否有某个数,一旦 ...
- 8-3 4Values Whose Sum is Zero 和为0的四个值
给定四个n元素集合 ABCD 要求分别从中取一个元素 abcd 使得他们的合为0 问有多少中取法 map果然炸了 #include<bits/stdc++.h> using n ...
- 【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) 解法:首先我们从最直接最暴力的方法开始思考:四重循 ...
随机推荐
- Newtonsoft.Json序列化字符串-格式化和时间格式问题
最近C#中需要将实体进行json序列化,使用了Newtonsoft.Json public static void TestJson() { DataTable d ...
- EF中外键重命名,打破原先的约束规则
本人建议玩code frist的人多用用System.ComponentModel.DataAnnotations和System.ComponentModel.DataAnnotations.Sche ...
- sqlserver2012——XML查询
1. CREATE TABLE STUDENT { S_ID INT, S_DATA xml } INSERT INTO STUDENT VALUES { 1, '<学生信息><姓名 ...
- 327. Count of Range Sum(inplace_marge)
Given an integer array nums, return the number of range sums that lie in [lower, upper] inclusive.Ra ...
- 根据rowid删除最新数据(rowid最大为最新数据)(转)
https://blog.csdn.net/liuyuehui110/article/details/43524379
- iTween研究院之学习笔记Move移动篇(一)
http://www.xuanyusong.com/archives/2052 iTween.MoveTo(): 让模型移动到一个位置,它的底层函数是通过动态的修改模型每一帧的transform.po ...
- codevs1553 互斥的数
1553 互斥的数
- 基础篇-密码文件.pgpass
密码文件包含字段 host:port:dbname:user:password port和dbname可以使用*号作通配符 在*nix系统中 ~/.pgpass 在windows系统中 %APPDAT ...
- docker镜像创建
1. 首选要创建一个Dockerfile文件,内容如下: FROM alpine:latest MAINTAINER lobin <lobin.hotmail.com> RUN apk ...
- PHP 扩展篇 _ 持续更新
记住这个网站:http://pecl.php.net/ PHP-Redis扩展更新时间:2019/05/06 PHP安装Redis 1:下载目前最新版的redis插件 wget http://pecl ...