对和排序,显然最小是a1+a2,次小a1+a3 然后穷举哪里是a2+a3 这样a1,a2,a3就求出来了

注意a2+a3只可能是前n+1项中的一个,所以穷举这步是O(n)的

接下来我们把已经确定的数的和找到并标记,那么下一个未标记的和就是a1+新的数,然后依次递推下去即可

 1 var v:array[0..50010] of boolean;
 2     a:array[0..50010] of longint;
 3     b:array[0..310] of longint;
 4     ans:array[0..10010,0..310] of longint;
 5     i,j,n,m,t:longint;
 6 
 7 procedure swap(var a,b:longint);
 8   var c:longint;
 9   begin
10     c:=a;
11     a:=b;
12     b:=c;
13   end;
14 
15 procedure sort(l,r:longint);
16   var i,j,x:longint;
17   begin
18     i:=l;
19     j:=r;
20     x:=a[(l+r) shr 1];
21     repeat
22       while a[i]<x do inc(i);
23       while x<a[j] do dec(j);
24       if not(i>j) then
25       begin
26         swap(a[i],a[j]);
27         inc(i);
28         dec(j);
29       end;
30     until i>j;
31     if l<j then sort(l,j);
32     if i<r then sort(i,r);
33   end;
34 
35 function find(l,r,x:longint):longint;
36   var m:longint;
37   begin
38     while l<=r do
39     begin
40       m:=(l+r) shr 1;
41       if a[m]=x then exit(m);
42       if a[m]>x then r:=m-1 else l:=m+1;
43     end;
44     exit(-1);
45   end;
46 
47 procedure check(i:longint);
48   var j,k,p,x,y:longint;
49   begin
50     fillchar(v,sizeof(v),false);
51     fillchar(b,sizeof(b),0);
52     if (a[1]+a[2]-a[i]) mod 2<>0 then exit;
53     b[1]:=(a[1]+a[2]-a[i]) div 2;
54     b[2]:=a[1]-b[1];
55     b[3]:=a[2]-b[1];
56     v[1]:=true; v[2]:=true; v[i]:=true;
57     p:=3;
58     for j:=4 to n do
59     begin
60       while (p<=m) and v[p] do inc(p);
61       if p>m then exit;
62       b[j]:=a[p]-b[1];
63       v[p]:=true;
64       for k:=2 to j-1 do
65       begin
66         if b[k]>=b[j] then exit;
67         x:=find(1,m,b[k]+b[j]);
68         if x=-1 then exit;
69         y:=x;
70         while (y>0) and (a[y]=a[x]) do dec(y);
71         inc(y);
72         while (y<=m) and (a[y]=a[x]) and v[y] do inc(y);
73         if (y>m) or (a[y]<>a[x]) or v[y] then exit;
74         v[y]:=true;
75       end;
76     end;
77     inc(t);
78     ans[t]:=b;
79   end;
80 
81 begin
82   readln(n);
83   m:=(n-1)*n div 2;
84   for i:=1 to m do
85     read(a[i]);
86   sort(1,m);
87   for i:=3 to n+1 do
88     if a[i]<>a[i-1] then check(i);
89   writeln(t);
90   for i:=1 to t do
91   begin
92     for j:=1 to n do
93       write(ans[i,j],' ');
94     writeln;
95   end;
96 end.
View Code

 

posted on 2015-06-04 22:03  acphile  阅读(230)  评论(0编辑  收藏  举报