您的位置:首页 > 其它

中途相遇法,哈希技术(和为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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: