POI #Year2012 #數學
考慮如果將 \(x_i\) 和 \(sum_i\) 都排序,那麼 \(sum_1=x_1+x_2\) ,\(sum_2=x_1+x_3\)
考慮列舉一個 \(sum_i=x_2+x_3\) ,此時就可以確定 \(x_1,x_2,x_3\)
假設當前確定到 \(i\) ,將已經確定的 \(x_i\) 組成的 \(sum\) 去掉,剩下的最小的 \(sum\) 一定為 \(x_1+x_{i+1}\)
考慮 \(x2+x3\) 實際上不可能是 \(sum_n\) 以後的數,所以只要列舉 \(n\) 個
// Author: xiaruize
const int N = 5e4 + 10;
int n, tot;
int sum[N];
int res[305][305], t;
int tmp[305];
multiset<int> s;
void calc(int x)
{
s.clear();
mms(tmp, 0);
if (((sum[1] + sum[2] + sum[x]) & 1))
return;
tmp[1] = (sum[1] + sum[2] + sum[x]) / 2 - sum[x];
tmp[2] = ((sum[1] + sum[2] + sum[x]) / 2 - sum[2]);
tmp[3] = ((sum[1] + sum[2] + sum[x]) / 2 - sum[1]);
if (tmp[1] < 0 || tmp[2] < 0 || tmp[3] < 0)
return;
rep(i, 1, tot) s.insert(sum[i]);
s.erase(s.find(sum[1]));
s.erase(s.find(sum[2]));
s.erase(s.find(sum[x]));
// debug(tmp, s);
rep(i, 4, n)
{
tmp[i] = ((*s.begin()) - tmp[1]);
if (tmp[i - 1] >= tmp[i])
return;
rep(j, 1, i - 1)
{
auto it = s.find(tmp[i] + tmp[j]);
if (it == s.end())
return;
s.erase(it);
}
}
t++;
rep(i, 1, n) res[t][i] = tmp[i];
}
void solve()
{
cin >> n;
tot = (n - 1) * n / 2;
rep(i, 1, tot) cin >> sum[i];
stable_sort(sum + 1, sum + tot + 1);
rep(i, 3, tot)
{
if (i == 3 || sum[i] != sum[i - 1])
calc(i);
if ((double)clock() / CLOCKS_PER_SEC * 1000.0 > 500)
break;
}
cout << t << endl;
rep(j, 1, t)
{
rep(i, 1, n)
{
cout << res[j][i] << ' ';
}
cout << endl;
}
}
#ifndef ONLINE_JUDGE
bool end_of_memory_use;
#endif
signed main()
{
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int testcase = 1;
// cin >> testcase;
while (testcase--)
solve();
#ifndef ONLINE_JUDGE
cerr << "Memory use:" << (&end_of_memory_use - &start_of_memory_use) / 1024.0 / 1024.0 << "MiB" << endl;
cerr << "Time use:" << (double)clock() / CLOCKS_PER_SEC * 1000.0 << "ms" << endl;
#endif
return 0;
}