UVA10125 Sumsets 题解
UVA10125 Sumsets 题解
洛谷原题链接
老师刚讲完,写篇题解理一下思路。
题意简述
题意其实很明确,给定一个集合
思路
对于等式
首先,对于链表中的每一个元素,考虑定义一个结构体以存储
//链表的建立
int head[MOD];
struct node {
int key, d, c;
int nxt;
};
inline int hashe(int x) {
return ((x % MOD) + MOD) % MOD;
}
node lis[MOD];
接着将储存答案的变量初始化为给定的最小值
//初始化
int n, a[N], cnt, ans;
inline void init() {
cnt = 0;
ans = -536870912;
memset(head, 0, sizeof(head));
}
接下来用上刚写的链表来维护所有的
//数据写入
for(int i = 1; i <= n; i ++) {
for(int j = 1; j <= n; j ++) {
if(i == j) continue;
lis[++ cnt] = {a[i] - a[j], a[i], a[j], head[hashe(a[i] - a[j])]};
head[hashe(a[i] - a[j])] = cnt;
}
}
接下来遍历链表寻找符合条件的
for(int i = 1; i <= n; i ++) {
for(int j = i + 1; j <= n; j ++) {
if(!head[hashe(a[i] + a[j])]) continue;
for(int x = head[hashe(a[i] + a[j])]; x; x = lis[x].nxt) {
if(lis[x].key != a[i] + a[j]) continue;
if(lis[x].d == a[i] || lis[x].c == a[i] || lis[x].d == a[j] || lis[x].c == a[j]) continue;
ans = max(ans, lis[x].d);
}
}
}
最后输出答案即可,时间复杂度
代码
#include <bits/stdc++.h>
using namespace std;
const int N = 1002, MOD = 1000007;
int n, a[N], cnt, ans;
int head[MOD];
struct node {
int key, d, c;
int nxt;
};
inline int hashe(int x) {
return ((x % MOD) + MOD) % MOD;
}
node lis[MOD];
inline void init() {
cnt = 0;
ans = -536870912;
memset(head, 0, sizeof(head));
}
signed main() {
ios :: sync_with_stdio(0), cin.tie(0);
while(cin >> n && n) {
init();
for(int i = 1; i <= n; i ++) cin >> a[i];
for(int i = 1; i <= n; i ++) {
for(int j = 1; j <= n; j ++) {
if(i == j) continue;
lis[++ cnt] = {a[i] - a[j], a[i], a[j], head[hashe(a[i] - a[j])]};
head[hashe(a[i] - a[j])] = cnt;
}
}
for(int i = 1; i <= n; i ++) {
for(int j = i + 1; j <= n; j ++) {
if(!head[hashe(a[i] + a[j])]) continue;
for(int x = head[hashe(a[i] + a[j])]; x; x = lis[x].nxt) {
if(lis[x].key != a[i] + a[j]) continue;
if(lis[x].d == a[i] || lis[x].c == a[i] || lis[x].d == a[j] || lis[x].c == a[j]) continue;
ans = max(ans, lis[x].d);
}
}
}
if(ans == -536870912) printf("no solution\n");
else printf("%d\n", ans);
}
return 0;
}