POI2012SQU-Squarks

xiaruize發表於2024-04-25

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;
}