显然
X
1
+
X
2
=
A
1
X_1+X_2=A_1
X1+X2=A1 ,
X
1
+
X
3
=
A
2
X_1+X_3=A_2
X1+X3=A2
(上面的
X
X
X 是递增的)
设
X
2
+
X
3
=
A
k
X_2+X_3=A_k
X2+X3=Ak ,则很容易得到比
A
k
A_k
Ak 小的只会是
X
1
+
X
i
X_1+X_i
X1+Xi
所以
k
≤
n
k\le n
k≤n ,我们枚举
X
2
+
X
3
=
A
k
X_2+X_3=A_k
X2+X3=Ak 中的
k
k
k (注意,重复的
A
k
A_k
Ak 不能被再次枚举)
根据小学奥数,我们得到
X
1
=
A
1
+
A
2
+
A
k
2
−
A
k
X_1=\frac{A_1+A_2+A_k}2-A_k
X1=2A1+A2+Ak−Ak
X
2
=
A
1
+
A
2
+
A
k
2
−
A
2
X_2=\frac{A_1+A_2+A_k}2-A_2
X2=2A1+A2+Ak−A2
X
3
=
A
1
+
A
2
+
A
k
2
−
A
1
X_3=\frac{A_1+A_2+A_k}2-A_1
X3=2A1+A2+Ak−A1
当然,如果
X
1
,
X
2
,
X
3
X_1,X_2,X_3
X1,X2,X3 中有一者不是正整数或者不严格递增,则我们不能用这样的
X
1
,
X
2
,
X
3
X_1,X_2,X_3
X1,X2,X3 导出一组解
用一个数据结构(支持删元素和询问最小值)存下
A
A
A 数组,先删掉
A
1
,
A
2
,
A
k
A_1,A_2,A_k
A1,A2,Ak
易得,这时候数据结构中存的最小值是
X
1
+
X
4
X_1+X_4
X1+X4
于是我们能求出这时
X
4
X_4
X4 的值
然后把
X
1
+
X
4
X_1+X_4
X1+X4 、
X
2
+
X
4
X_2+X_4
X2+X4 、
X
3
+
X
4
X_3+X_4
X3+X4 从数据结构里删除
对于所有的
4
≤
i
≤
n
4\le i\le n
4≤i≤n 都一样
(1)这时数据结构中存的最小值为
X
1
+
X
i
X_1+X_i
X1+Xi
(2)计算出
X
i
X_i
Xi ,如果
X
i
≤
X
i
−
1
X_i\le X_{i-1}
Xi≤Xi−1 则停止这次求解
(3)对于任意
1
≤
j
<
i
1\le j<i
1≤j<i ,将
X
j
+
X
i
X_j+X_i
Xj+Xi 从数据结构中删除,如果
X
j
+
X
i
X_j+X_i
Xj+Xi 不在数据结构内则停止这次求解
如果所有的
4
≤
i
≤
n
4\le i\le n
4≤i≤n 都能执行完上述过程,则我们得到了一组解
至于如何实现这个数据结构,那就各凭本事了
复杂度
O
(
n
3
log
n
)
O(n^3\log n)
O(n3logn) ,但很难达到上界
Code
#include<map>#include<cmath>#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>#define For(i, a, b) for (i = a; i <= b; i++)inlineintread(){int res =0;bool bo =0;char c;while(((c =getchar())<'0'|| c >'9')&& c !='-');if(c =='-') bo =1;else res = c -48;while((c =getchar())>='0'&& c <='9')
res =(res <<3)+(res <<1)+(c -48);return bo ?~res +1: res;}constint N =305, M =5e4+5;int n, m, a[M], anst, ans[N][N], now[N], top, stk[M], tot, b[M], cnt[M];
std::map<int,int> arr;voidrever(){while(top) cnt[arr[stk[top--]]]++;}voidjiejuediao(int rd3){int i, j, tmp = a[1]+ a[2]+ a[rd3]>>1, p =1;if(a[1]+ a[2]+ a[rd3]&1)return;
now[1]= tmp - a[rd3]; now[2]= tmp - a[2];
now[3]= tmp - a[1];if(now[1]<=0|| now[2]<= now[1]|| now[3]<= now[2])return;
cnt[arr[a[1]]]--; cnt[arr[a[2]]]--; cnt[arr[a[rd3]]]--;
stk[++top]= a[1]; stk[++top]= a[2]; stk[++top]= a[rd3];while(p <= tot &&!cnt[p]) p++;
For (i,4, n){
now[i]= b[p]- now[1];if(now[i]<= now[i -1])returnrever();
For (j,1, i -1){
tmp = arr[now[j]+ now[i]];if(!tmp ||!cnt[tmp])returnrever();else cnt[tmp]--, stk[++top]= now[j]+ now[i];}while(p <= tot &&!cnt[p]) p++;}
anst++;
For (i,1, n) ans[anst][i]= now[i];rever();}intmain(){int i, j;
n =read(); m = n *(n -1)>>1;
For (i,1, m) a[i]=read();
std::sort(a +1, a + m +1);
For (i,1, m)if(i ==1|| a[i]!= a[i -1]) b[++tot]= a[i], cnt[tot]=1;else cnt[tot]++;
For (i,1, tot) arr[b[i]]= i;
For (i,3, n)if(i ==3|| a[i]!= a[i -1])jiejuediao(i);
std::cout << anst << std::endl;
For (i,1, anst){
For (j,1, n)printf("%d ", ans[i][j]);printf("\n");}return0;}