51nodP1090 3个数和为0

51nodP1090 3个数和为0

1、首先我们处理出每两个数的和,两个数升序排列,即强制第二个数大于第三个数,
然后我们按照 和 降序排列,这样两个数的和
的相反数 就可以作为第一个数 ,因为降序 所以第一个数的值一定是单调的,
2、然后我们就可以将前面处理出来的每个数的和枚举过去,看他的相反数是否出现过, 用 map 维护 
因为互不相同 这点很重要 否则我的方法就不行了 233,然后判断一下这个第一个数是否小于第二个数
小于则说明这种 方案是合法的,然后我们就可以直接输出了,因为我们前面限制的条件,所以这样一定是按
字典序从小到大输出的

 

 1 #include <cstdio>
 2 #include <cmath>
 3 #include <cstdlib>
 4 #include <cstring>
 5 #include <string>
 6 #include <algorithm>
 7 #include <iomanip>
 8 #include <iostream>
 9 #include <map>
10 using namespace std ;
11 
12 struct node{
13     int x,y,sum ; 
14 }b[1000011];
15 int n,cnt,ans ; 
16 int a[1011] ;
17 map <int,int> mp ;
18 
19 inline bool cmp(node u,node v) 
20 {
21     if(u.sum!=v.sum) return u.sum > v.sum ;
22     return a[ u.x ] < a[ v.x ] ;  
23 }
24 
25 int main() 
26 {
27     scanf("%d",&n) ; 
28     for(int i=1;i<=n;i++) 
29         scanf("%d",&a[ i ]),mp[ a[i] ] = 1 ;
30     sort(a+1,a+n+1) ;
31     for(int i=1;i<=n-1;i++) 
32         for(int j=i+1;j<=n;j++ ) 
33             b[++cnt] = (node){ i,j,a[i]+a[j] } ;
34     sort(b+1,b+cnt+1,cmp) ;  
35     for( int i=1;i<=cnt;i++ ) 
36     {
37         if( mp[ -b[ i ].sum ]  ) 
38         {
39             if( -b[ i ].sum < a[ b[i].x ] ) 
40                 ans++,printf( "%d %d %d\n",-b[i].sum,a[ b[i].x ],a[ b[i].y ] ) ;
41         }
42     }
43     if(!ans) printf("No Solution\n") ; 
44     return 0 ; 
45 } 

 

posted @ 2017-05-26 14:31  third2333  阅读(269)  评论(0编辑  收藏  举报