#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <vector>
#include <cmath>
using namespace std;
const int N = 2e3;
int n, arr[N + 5], cnt[N + 5], maxv;
vector<vector<int>> res;
vector<int> ans;
//现在多少数
//最大是多少
void solve(int u, int maxnow)
{
if (u == n)
{
res.push_back(ans);
sort(res.back().begin(), res.back().end());
return;
}
//最大数 只能构建一次 如果是0了 那么就往前找最大的
while (cnt[maxnow] == 0)
--maxnow;
//如果最大的次数 是 >2
//那么这个方案就一定不合法
if (cnt[maxnow] > 2)
return;
//如果为0 就说明是 maxnow -0
// maxnow+k - (k+0)
//同时加2 个
if (cnt[maxnow] == 2)
{
bool ok = true;
ans.push_back(maxnow);
//构建k
ans.push_back(maxv - maxnow);
//当加入这两个数字之后
//判断是否 是否还能构成原来的序列
//也就是 check 有没有出现 没有出现过的差
//同时也把能出现差的次数减去
//那么最后构建的时候 最大的差就只是1 或者 2
for(int i = 0; i < u; ++ i)
if (-- cnt[abs(ans[i] - ans[u])] < 0)
ok = false;
for(int i = 0; i < u + 1; ++ i)
if (-- cnt[abs(ans[i] - ans[u + 1])] < 0)
ok = false;
//如果没有出现过的话 那么就是可以继续往下找
if(ok)
solve(u + 2, maxnow);
//不能 就 恢复现场
for(int i = 0; i < u; ++ i)
++ cnt[abs(ans[i] - ans[u])];
for(int i = 0; i < u + 1; ++ i)
++ cnt[abs(ans[i] - ans[u + 1])];
ans.pop_back();
ans.pop_back();
return;
}
//只出现一次
//就 只加入一个数字
//分别check
ans.push_back(maxnow);
bool ok = true;
for(int i = 0; i < u; ++ i)
if (-- cnt[abs(ans[i] - ans[u])] < 0)
ok = false;
if(ok)
solve(u + 1, maxnow);
for(int i = 0; i < u; ++i)
++ cnt[abs(ans[i] - ans[u])];
ans.pop_back();
ok = true;
ans.push_back(maxv - maxnow);
for(int i = 0; i < u; ++ i)
if (-- cnt[abs(ans[i] - ans[u])] < 0)
ok = false;
if(ok)
solve(u + 1, maxnow);
for(int i = 0; i < u; ++i)
++ cnt[abs(ans[i] - ans[u])];
ans.pop_back();
}
int main()
{
cin >> n;
for (int i = 1; i <= n * (n - 1) / 2; ++i)
{
cin >> arr[i];
if (arr[i] >= 1000)
{
cout << 0 << endl;
return 0;
}
cnt[arr[i]] += 1;
//出现的最大数
maxv = max(maxv, arr[i]);
}
//如果最大数出现了两次,那么就肯定有负数
if (cnt[maxv] > 1)
{
cout << 0 << endl;
return 0;
}
//x1 为0
//那么最大就只能是maxv
ans.push_back(0);
ans.push_back(maxv);
cnt[maxv] = 0;
solve(2, maxv);
sort(res.begin(), res.end());
int sum = res.size();
printf("%d\n", sum);
for (int i = 0; i < sum; ++ i)
{
for (int j = 0; j < n; ++ j)
cout<<res[i][j]<<" ";
cout << endl;
}
return 0;
}
2019-2020 ICPC Asia Taipei-Hsinchu Regional Contest I——The Spectrum dfs+剪枝
猜你喜欢
转载自www.cnblogs.com/QingyuYYYYY/p/12742452.html
今日推荐
周排行