中途相遇法,哈希技术(和为0的4个值,uva 1152)
2016-08-23 15:55
337 查看
题目具有对称性,则可以同时从两边出发来找答案,因为时间复杂度由最大的决定,因此让两边时间复杂度尽量一样可以降低总体的时间复杂度,此题中n^2logn+n^2logn<n^4+1。虽然平摊时间复杂度后就得多考虑一个检索的时间复杂度,然而还是更快。双向广度优先搜索就有点像,虽然双向的时间复杂度都相同,但是平摊了数据之后,n^2+n^2<(2n)^2+1。
试了下map,9秒超时,用哈希3.540秒。还是快很多的。
因为map随着数据量的增多,logn的时间复杂度开始拖慢速度。
而哈希大部分时候都是O(1),极端情况下是O(n)。
极端情况一般都不用考虑,除非题目是特殊设计专门来狙击hash的,但这几乎不可能,谁那么蛋疼。
普遍的情况下hash还是远快的。
hashsize开大一点,也会快很多。
以空间换时间嘛。
hash技术本来就是在空间与时间中寻找一个平衡点的。
紫书上讲的哈希是开了一个很大的next数组的,事实上很多时候都开不下吧。
只能new节点或者用vector了。
vector更好用。
#include<bits/stdc++.h>
#define hashsize 1000000
using namespace std;
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
vector<int>Hash[hashsize];
int n;
scanf("%d",&n);
vector<int>vec[4];
while(n--)
{
int temp;
for(int i=0;i<4;i++)
{
scanf("%d",&temp);
vec[i].push_back(temp);
}
}
for(unsigned int i=0;i<vec[0].size();i++)
for(unsigned int j=0;j<vec[1].size();j++)
{
int s=vec[0][i]+vec[1][j];
int h=abs(s)%hashsize;
Hash[h].push_back(s);
}
int ans=0;
for(unsigned int i=0;i<vec[2].size();i++)
for(unsigned int j=0;j<vec[3].size();j++)
{
int s=-vec[2][i]-vec[3][j];
int h=abs(s)%hashsize;
int cnt=0;
for(unsigned int k=0;k<Hash[h].size();k++)
if(Hash[h][k]==s)
cnt++;
ans+=cnt;
}
printf("%d\n",ans);
if(t) puts("");
}
return 0;
}
试了下map,9秒超时,用哈希3.540秒。还是快很多的。
因为map随着数据量的增多,logn的时间复杂度开始拖慢速度。
而哈希大部分时候都是O(1),极端情况下是O(n)。
极端情况一般都不用考虑,除非题目是特殊设计专门来狙击hash的,但这几乎不可能,谁那么蛋疼。
普遍的情况下hash还是远快的。
hashsize开大一点,也会快很多。
以空间换时间嘛。
hash技术本来就是在空间与时间中寻找一个平衡点的。
紫书上讲的哈希是开了一个很大的next数组的,事实上很多时候都开不下吧。
只能new节点或者用vector了。
vector更好用。
#include<bits/stdc++.h>
#define hashsize 1000000
using namespace std;
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
vector<int>Hash[hashsize];
int n;
scanf("%d",&n);
vector<int>vec[4];
while(n--)
{
int temp;
for(int i=0;i<4;i++)
{
scanf("%d",&temp);
vec[i].push_back(temp);
}
}
for(unsigned int i=0;i<vec[0].size();i++)
for(unsigned int j=0;j<vec[1].size();j++)
{
int s=vec[0][i]+vec[1][j];
int h=abs(s)%hashsize;
Hash[h].push_back(s);
}
int ans=0;
for(unsigned int i=0;i<vec[2].size();i++)
for(unsigned int j=0;j<vec[3].size();j++)
{
int s=-vec[2][i]-vec[3][j];
int h=abs(s)%hashsize;
int cnt=0;
for(unsigned int k=0;k<Hash[h].size();k++)
if(Hash[h][k]==s)
cnt++;
ans+=cnt;
}
printf("%d\n",ans);
if(t) puts("");
}
return 0;
}
相关文章推荐
- UVA 1152 4 Values Whose Sum is Zero 和为0的4个值 (中途相遇)
- uva 1152 和为0的4个值(中途相遇法)
- uva1152 - 4 Values whose Sum is 0(枚举,中途相遇法)
- 8.5-237-uva1152-中途相遇法-二分法
- UVA 1152 --4 Values whose Sum is 0(枚举--中途相遇法)
- UVa 1152 (中途相遇法) 4 Values whose Sum is 0
- uva 1152 4 Values whose Sum is 0(二分_中途相遇|| hash)
- (白书训练计划)UVa 1152 4 Values whose Sum is 0(中途相遇法。。)
- uva 1152 二分查找+中途相遇法
- UVa1152 4 Values whose Sum is 0 (中途相遇法+二分)
- UVA - 1152 4 Values whose Sum is 0 【中途相遇法/二分】
- Uva1152 查找优化的四种方法 中途相遇法
- UVA 1152 4 Values whose Sum is 0 (枚举+中途相遇法)(+Java版)(Java手撕快排+二分)
- UVa 1152 - 4 Values whose Sum is 0(中途相遇)
- UVA 1152 4 Values whose Sum is 0 中途相遇法 二分查找
- Uva1152 4 Values whose Sum is 0 【中途相遇+二分】【例题8-3】
- UVa 10125 - Sumsets (中途相遇法 hash)
- uva 1326 Jurassic Remains(中途相遇法+位运算)
- UVa 1152 和为0的4个值(二分查找)
- UVALive 2965-Jurassic Remains (Mitm)中途相遇法+bitmask