其他分享
首页 > 其他分享> > UVA10125 Sumsets

UVA10125 Sumsets

作者:互联网

Sumsets

给定数集 \(S\),求互不相等的四个数满足 \(a+b+c=d(a,b,c,d\in S)\) 中 \(d\) 的最大值。

转化为 \(a+b=d-c\),然后是套路的 meet in the middle。

使用手写 Hash_Table 可以少一个 log,但是常数略大。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;

const int N = 1010;
const int M = 1e6 + 10;
const int MOD = 999991;
const int INF = 1 << 30;
int n, s[N];

int read(){
	int x = 0, f = 1; char c = getchar();
	while(c < '0' || c > '9') f = (c == '-') ? -1 : 1, c = getchar();
	while(c >= '0' && c <= '9') x = x * 10 + c - 48, c = getchar();
	return x * f;
}

struct Hash_Table{
	int cnt, head[M];
	struct Table{int nxt, val, a, b;} ed[M];
	
	int Get(int x){return abs(x) % MOD + 1;}
	
	void clear(){
		cnt = 0;
		memset(head, 0, sizeof(head));
	}
	
	void insert(int v, int a, int b){
		int u = Get(v);
		ed[++ cnt] = (Table){head[u], v, a, b};
		head[u] = cnt;
	}
	
	bool query(int v, int c, int d){
		int u = Get(v);
		for(int i = head[u]; i; i = ed[i].nxt)
			if(ed[i].val == v){
				int a = ed[i].a, b = ed[i].b;
				if(a != c && a != d && b != c && b != d) return true;
			}
		return false;
	}
} Hash;

int main(){
	while(n = read()){
		for(int i = 1; i <= n; i ++) s[i] = read();
		Hash.clear();
		for(int a = 1; a < n; a ++)
			for(int b = a + 1; b <= n; b ++)
				Hash.insert(s[a] + s[b], a, b);
		int ans = - INF;
		for(int c = 1; c <= n; c ++)
			for(int d = 1; d <= n; d ++)
				if(c != d && Hash.query(s[d] - s[c], c, d))
					ans = max(ans, s[d]);
		if(ans == - INF) puts("no solution");
		else printf("%d\n", ans);
	}
	return 0;
}

标签:const,int,UVA10125,middle,1e6,include,Sumsets
来源: https://www.cnblogs.com/lpf-666/p/14803885.html