版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/sizeof_you/article/details/83010214
传送门
贪心好题啊qwq
首先给这些和排个序,最小的那个一定是
,次小的一定是
,然后比
小的一定是
所以,
一定排在第
到第
的某个位置,可以枚举
知道了 就可以知道 分别是多少,剩下的数中 一定是最小的,然后我们也可以知道 ···以此类推,就可以将原数列全部求出
至于如何实现,用一个 就好了
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<set>
#define maxn 90000
#define LL long long
using namespace std;
int n,a[maxn],tot,ans[305],res[305][305],cnt;
multiset<int> s;
inline int rd(){
int x=0,f=1;char c=' ';
while(c<'0' || c>'9') f=c=='-'?-1:1,c=getchar();
while(c<='9' && c>='0') x=x*10+c-'0',c=getchar();
return x*f;
}
inline void solve(int sum){
s.clear();
for(int i=1;i<=tot;i++) s.insert(a[i]);
if((a[1]+a[2]+sum)&1) return;
ans[1]=(a[1]+a[2]-sum)>>1;
ans[2]=(a[1]+sum-a[2])>>1;
ans[3]=(a[2]+sum-a[1])>>1;
if(ans[1]<0 || ans[2]<0 || ans[3]<0) return;
s.erase(s.find(ans[1]+ans[2]));
s.erase(s.find(ans[2]+ans[3]));
s.erase(s.find(ans[1]+ans[3]));
for(int i=4;i<=n;i++){
ans[i]=*s.begin()-ans[1];
if(ans[i]<0) return;
for(int j=1;j<i;j++){
int tmp=ans[j]+ans[i];
if(s.find(tmp)==s.end()) return;
s.erase(s.find(tmp));
}
}
for(int i=2;i<=n;i++)
if(ans[i]<=ans[i-1])
return;
cnt++;
for(int i=1;i<=n;i++)
res[cnt][i]=ans[i];
}
int main(){
n=rd(); tot=n*(n-1)>>1;
for(int i=1;i<=tot;i++) a[i]=rd();
sort(a+1,a+tot+1);
for(int i=3;i<=n;i++)
if(i==3 || a[i]!=a[i-1])
solve(a[i]);
printf("%d\n",cnt);
for(int i=1;i<=cnt;i++){
for(int j=1;j<=n;j++) printf("%d ",res[i][j]);
printf("\n");
}
return 0;
}