[BZOJ2797][Poi2012]Squarks

2797: [Poi2012]Squarks

Time Limit: 10 Sec  Memory Limit: 64 MB
Submit: 211  Solved: 89
[Submit][Status][Discuss]

Description


设有n个互不相同的正整数{X1,X2,...Xn},任取两个Xi,Xj(i≠j),能算出Xi+Xj。
现在所有取法共n*(n-1)/2个和,要你求出X1,X2,...Xn。

 

Input

第一行一个正整数n (3<=n<=300)。
第二行n*(n-1)/2个正整数(每个正整数不超过10^8),表示任取两个Xi,Xj(i≠j)算出的n*(n-1)/2个和。

 

Output

第一行一个正整数k,表示方案数。测试数据保证至少存在一种方案。
下面k行每行给出递增的n个正整数。方案按照{Xi}的最小值从大到小输出。

 

Sample Input

Sample Input 1
4
3 5 4 7 6 5


Sample Input 2
4
11 17 12 20 21 15

Sample Output

Sample Output 2
2
4 7 8 13
3 8 9 12

Sample Output 1
1
1 2 3 4

HINT

 

Source

[Submit][Status][Discuss]


先把数列排一下序,a1一定是x1+x2,a2一定是x1+x3。如果知道x2+x3的话,就可以求出x1~x3了。

这样的话可以枚举x2+x3,然后求出x1~x3之后删掉这里面的和,最小的一定是x1+x4了,这样又可以求出来x4。

因为n比较小,这样就可以过了。

 1 #include<set>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #define N 305
 5 using namespace std;
 6 inline int read()
 7 {
 8     int x=0,f=1;char ch=getchar();
 9     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
10     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
11     return x*f;
12 }
13 int n,tot,a[N*N],ans[N][N],x[N];
14 multiset<int>s;
15 void solve(int a3)
16 {
17     s.clear();
18     for(int i=1;i<=n*(n-1)/2;i++)
19     s.insert(a[i]);
20     if(a[1]+a[2]+a3&1)return;
21     x[1]=a[1]+a[2]-a3>>1;
22     x[2]=a[1]-a[2]+a3>>1;
23     x[3]=-a[1]+a[2]+a3>>1;
24     if(x[1]<0||x[2]<0||x[3]<0)return;
25     s.erase(s.find(a[1]));
26     s.erase(s.find(a[2]));
27     s.erase(s.find(a3));
28     for(int i=4;i<=n;i++)
29     {
30         x[i]=*s.begin()-x[1];
31         if(x[i]<0)return;
32         for(int j=1;j<i;j++)
33         {
34             int t=x[j]+x[i];
35             if(s.find(t)==s.end())return;
36             s.erase(s.find(t));
37         }
38     }
39     for(int i=2;i<=n;i++)
40     if(x[i]<=x[i-1])return;
41     for(int i=1;i<=n;i++)
42     ans[tot][i]=x[i];
43     tot++;
44 }
45 int main()
46 {
47     n=read();
48     for(int i=1;i<=n*(n-1)/2;i++)a[i]=read();
49     sort(a+1,a+n*(n-1)/2+1);
50     for(int i=3;i<=n;i++)
51     if(i==3||a[i]!=a[i-1])
52     solve(a[i]);
53     printf("%d\n",tot);
54     for(int j=0;j<tot;j++,puts(""))
55     for(int i=1;i<=n;i++)
56     printf("%d ",ans[j][i]);
57 }
View Code

(PS:我发现有很多人特别快,不知道是怎么做的。。)

posted @ 2016-02-15 20:34  xuruifan  阅读(320)  评论(1编辑  收藏  举报