为了能到远方,脚下的每一步都不能少.|

园龄:粉丝:关注:

POI2012SQU-Squarks

POI #Year2012 #数学

考虑如果将 xisumi 都排序,那么 sum1=x1+x2sum2=x1+x3

考虑枚举一个 sumi=x2+x3 ,此时就可以确定 x1,x2,x3

假设当前确定到 i ,将已经确定的 xi 组成的 sum 去掉,剩下的最小的 sum 一定为 x1+xi+1

考虑 x2+x3 实际上不可能是 sumn 以后的数,所以只要枚举 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;
}

本文作者:xiaruize's Blog

本文链接:https://www.cnblogs.com/xiaruize/p/18156738

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   xiaruize  阅读(4)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起