Known set pairwise sum

Known set pairwise sum

topic

Given the sum of the two elements in the set, find the elements in the set

Ideas

Draw a matrix first

a 1 a_1 a1 + a 2 a_2 a2 a 1 a_1 a1 + a 3 a_3 a3 a 1 a_1 a1 + a 4 a_4 a4
- a 2 a_2 a2 + a 3 a_3 a3 a 2 a_2 a2 + a 4 a_4 a4
- - a 3 a_3 a3 + a 4 a_4 a4

Among them a 1, a 2 ... a_1, a_2 ...a1,a2. . . It is in ascending order of
easy to know, by the single matrix value from left to right, top to bottom monocytogenes.
So if we can get the numbersa 1, a 2,..., An a_1, a_2,..., a_nthat appeared in the first n columns firsta1,a2,...,an
A first n + 1 n + 1n+The first element in column 1 is the smallest element in the remaining sum,an + 1 a_{n+1}an+1It was confirmed.
With the same induction method, all results can be obtained (maybe it can be called recursion?)

Then only need to traverse a 1, a 2 a_1, a_2a1,a2Possible value range, and then inductively check whether the remaining sum can satisfy a 3,..., An a_3,...,a_na3,...,anIf you can, it is a set of answers

The complexity should be O (S 1. (FS) N) O(S_1. (F_S )^N)O(S1.(FS)N )
whereS 1 S_1S1Is the minimum sum value, NNN is the number of set elements,FS F_SFSIs the complexity required to find the minimum value, the set I used, here is Log N LogNL o g N

Attach code

#include <iostream>
#include <algorithm>
#include <set>
using namespace std;
#define CNT 5051
int N;
multiset<int> sum;
int ans[101];
bool flag = 0;
void SolveLayer(int layer) {
	if (flag)
		return;

	if (layer == N) {
		cout << ans[1];
		for (int i = 2; i <= N; i++)
			cout << " " <<  ans[i];
		cout << endl;
		flag = 1;
		return;
	}
	else {
		int vmin = *sum.begin();
		int layer_num = vmin - ans[1];
		ans[layer + 1] = layer_num;
		for (int i = 2; i <= layer; i ++) {
			if (sum.find(layer_num + ans[i]) == sum.end())
				return;
		}

		for (int i = 1; i <= layer; i++) {
			auto iter = sum.find(layer_num + ans[i]);
			sum.erase(iter);
		}

		SolveLayer(layer + 1);

		for (int i = 1; i <= layer; i++) {
			sum.insert(layer_num + ans[i]);
		}
	}
}

void Solve() {
	int v1 = *sum.begin();
	sum.erase(v1);
	int maxv = (v1 - 1) / 2;
	for (int i = 1; i <= maxv; i++) {
		ans[1] = i;
		ans[2] = v1 - i;
		SolveLayer(2);
	}
}

int main() {
	cin >> N;
	int cnt = (N * (N - 1)) / 2;
	for (int i = 1; i <= cnt; i ++) {
		int k;
		cin >> k;
		sum.insert(k);
	}

	Solve();
	return 0;
}

Guess you like

Origin blog.csdn.net/zhongershuchong/article/details/84669140
sum