Problem B: Pairsumonious Numbers
For 10 > N > 2 numbers we form N*(N-1)/2 sums by adding every pair of the numbers. Your task is to find the N numbers given the sums. Each line of input contains N followed by N*(N-1)/2 integer numbers separated by a space. For each line of input, output one line containing N integers in non-descending order such that the input numbers are pairwise sums of the N numbers. If there is more than one solution, any one will do; if there is no solution, print "Impossible".Sample input
3 1269 1160 1663 3 1 1 1 5 226 223 225 224 227 229 228 226 225 227 5 216 210 204 212 220 214 222 208 216 210 5 -1 0 -1 -2 1 0 -1 1 0 -1 5 79950 79936 79942 79962 79954 79972 79960 79968 79924 79932
Output for sample input
383 777 886 Impossible 111 112 113 114 115 101 103 107 109 113 -1 -1 0 0 1 39953 39971 39979 39983 39989
参考了思路:
http://blog.csdn.net/liukaipeng/article/details/3371330
#include <cstdio>
#include <cstdlib>
#include <cassert>
#include <list>
#include <algorithm>
#include <iterator>
#include <iostream>
using namespace std;
#define MAX 15
int a[MAX];
int s[MAX * MAX];
int n;
void Solve () {
sort (::s + 1, ::s + n*(n-1)/2 + 1);
int s12 = ::s[1]; // s12 = a1 + a2
int s13 = ::s[2]; // s13 = a1 + a3
bool isOK;
for (int i=3; i<=n; ++i) {
int s23 = ::s[i]; // s23 = a2 + a3
a[1] = (s12 + s13 - s23) / 2;
a[2] = (s12 + s23 - s13) / 2;
a[3] = (s13 + s23 - s12) / 2;
if (a[1] + a[2] != s12 || a[2] + a[3] != s23 || a[1] + a[3] != s13) {
isOK = false;
continue;
}
list <int> s;
// copy ::s[] to the list except s12, s13, and s23
copy (::s + 3, ::s + i, back_inserter <list <int> > (s));
copy (::s + i + 1, ::s + n*(n-1)/2 + 1, back_inserter <list <int> > (s));
isOK = true;
for (int k=4; k<=n && isOK; ++k) {
// in the front of the list is a1+ak
a[k] = s.front() - a[1];
// remove a1+ak, a2+ak, ..., a(k-1)+ak from the list
for (int t=1; t<k; ++t) {
list <int>::iterator it = find (s.begin(), s.end(), a[t] + a[k]);
if ((isOK = (it != s.end()))) {
s.erase (it);
} else {
break;
}
}
}
if (isOK) {
// print the answer
sort (a + 1, a + 1 + n);
copy (a + 1, a + n, ostream_iterator <int> (cout, " "));
cout << a[n] << "\n";
break;
}
}
if (! isOK) {
cout << "Impossible\n";
}
}
int main () {
while (scanf ("%d", &n) == 1) {
for (int i=1; i<=n*(n-1)/2; ++i) {
scanf ("%d", &s[i]);
}
Solve ();
}
return 0;
}