题目大意:给n个数的所有和,求这n个数的所有可能方案
首先最小的是x1+x2,第二小的是x1+x3,接着O(N)枚举x2+x3,就能算出x1,x2,x3,然后从所有的和中删掉这3个和,剩下的最小的一定是x1+x4,这样就求出了x4,然后再删掉这三个新的和,又能求出x1+x5....以此类推
没有spj,但是貌似1A了...
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<set>
#define N 100010
using namespace std;
multiset<int>S;
int X[N];
int ans[310][310],cnt;
int n;
bool solveit()
{
int i=4,j;
while(i<=n)
{
X[i]=*(S.begin())-X[1];
if(X[i]<X[i-1]) continue;
for(j=1;j<i;j++)
{
if(S.find(X[i]+X[j])==S.end()) return false;
S.erase(S.find(X[i]+X[j]));
}
i++;
}
return true;
}
int a[N];
int main()
{
scanf("%d",&n);
int i,j,x,y,tot=n*(n-1)/2;
for(i=1;i<=tot;i++)
scanf("%d",&a[i]);
int x12,x13,x23;
sort(a+1,a+tot+1);
for(i=3;i<=n+1;i++)
if(a[i]!=a[i-1])
{
x12=a[1];x13=a[2];
x23=a[i];
if((x12+x13+x23)%2==1) continue;
X[1]=(x12+x13+x23)/2-x23;
X[2]=(x12+x13+x23)/2-x13;
X[3]=(x12+x13+x23)/2-x12;
if(!(X[1]<=X[2]&&X[2]<=X[3])) continue;
S.clear();
for(j=3;j<=tot;j++)
if(i!=j)
S.insert(a[j]);
if(solveit())
{
cnt++;
for(j=1;j<=n;j++)
ans[cnt][j]=X[j];
}
}
printf("%d\n",cnt);
for(i=1;i<=cnt;i++)
{
for(j=1;j<=n;j++)
printf("%d ",ans[i][j]);
puts("");
}
}