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 }