POJ 2549 Sumsets hash值及下标

时间:2021-09-04 21:03:38

题目大意:
找到几何中的4个数字使他们能够组成 a+b+c=d , 得到最大的d值

我们很容易想到a+b = d-c

那么将所有a+b的值存入hash表中,然后查找能否在表中找到这样的d-c的值即可

因为4个数字都不能相同,那么我们同时要在hash表中记录相加两个数的下标,然后查找的时候还要进行下标判断

这里用二分查找也可以,但是能用hash还是hash快地多了

这里第一次写到对负数进行hash,还是傻傻地 val%MOD , 但是负数得到的模值为负,作为hash的下标会RE,所以RE了一发,还是看别人的题解才找到这个错误,要谨记

遇到负数要先取绝对值后再hash

 #include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <climits>
using namespace std;
#define N 1010
#define MOD 1000007
#define base 31 struct HashNode{
int val , next;
int x , y;
}_hash[MOD]; int head[MOD+] , k , a[N]; void insertHash(int key , int x , int y)
{
int pos = ((key<)?-key:key)%MOD;
_hash[k].val = key , _hash[k].next = head[pos] , _hash[k].x=x , _hash[k].y=y;
head[pos] = k++;
} bool searchHash(int key , int a , int b)
{
int pos = ((key<)?-key:key)%MOD;
for(int i=head[pos] ; ~i ; i=_hash[i].next){
if(key == _hash[i].val){
if(a==_hash[i].x||a==_hash[i].y||b==_hash[i].x||b==_hash[i].y) continue;
return true;
}
}
return false;
} bool cmp(int a , int b)
{
return a>b;
} int main()
{
#ifndef ONLINE_JUDGE
freopen("a.in" , "r" , stdin);
#endif // ONLINE_JUDGE
int n;
while(scanf("%d" , &n) , n)
{
memset(head , - , sizeof(head));
k=;
for(int i= ; i<n ; i++) scanf("%d" , &a[i]);
sort(a , a+n , cmp);
for(int i= ; i<n ; i++){
for(int j=i+ ; j<n ; j++){
int v = a[i]+a[j];
insertHash(v , i , j);
}
}
int ret = INT_MIN;
for(int i= ; i<n ; i++){
for(int j= ; j<n ; j++){
if(i==j) continue;
int v = a[i]-a[j];
if(searchHash(v , i , j)){
ret = max(ret , a[i]);
break;
}
}
if(ret!=INT_MIN) break;
}
if(ret==INT_MIN) printf("no solution\n");
else printf("%d\n" , ret);
}
return ;
}