51Nod 1090 3个数和为0 set 二分优化
给出一个长度为N的无序数组,数组中的元素为整数,有正有负包括0,并互不相等。
从中找出所有和 = 0的3个数的组合。如果没有这样的组合,输出No Solution。
如果有多个,按照3个数中最小的数从小到大排序,如果最小的数相等则按照第二小的数排序。
Input
第1行,1个数N,N为数组的长度(0 <= N <= 1000)
第2 - N + 1行:A[i](-10^9 <= A[i] <= 10^9)
Output
如果没有符合条件的组合,输出No Solution。
如果有多个,按照3个数中最小的数从小到大排序,如果最小的数相等则继续按照第二小的数排序。
每行3个数,中间用空格分隔,并且这3个数按照从小到大的顺序排列。
Input示例
7
-3
-2
-1
0
1
2
3
Output示例
-3 0 3
-3 1 2
-2 -1 3
-2 0 2
-1 0 1
思路:set暴力+优化
1.纯set暴力
1 #include <bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 set<int> s,t; 5 set<int>::iterator it,jt,kt; 6 int main() { 7 ios::sync_with_stdio(false); 8 int n,data,sum=0; 9 cin>>n; 10 for(int i=1;i<=n;++i) { 11 cin>>data; 12 s.insert(data); 13 } 14 int flag=0; 15 for(it=s.begin();it!=s.end();++it) { 16 sum=0; 17 sum-=*it; 18 t=s; 19 jt=t.find(*it); 20 jt++; 21 for(;jt!=t.end();++jt) { 22 data=sum-*jt; 23 kt=t.find(data); 24 if(kt!=t.end()&&(*kt!=*jt)&&(*kt>*jt)) { 25 cout<<*it<<" "<<*jt<<" "<<*kt<<endl; 26 flag=1; 27 t.erase(*kt); 28 } 29 } 30 } 31 if(!flag) cout<<"No Solution"<<endl; 32 return 0; 33 }
2.set+二分优化
1 #include <iostream> 2 #include <set> 3 using namespace std; 4 set<int> s; 5 set<int>::iterator it,jt,kt; 6 int main() { 7 ios::sync_with_stdio(false); 8 int n,data; 9 cin>>n; 10 for(int i=1;i<=n;++i) { 11 cin>>data; 12 s.insert(data); 13 } 14 int flag=0; 15 for(it=s.begin();it!=s.end();++it) { 16 if(*it>=0) break; 17 jt=it; 18 jt++; 19 kt=prev(s.end()); 20 while(*jt<*kt) { 21 if(*it+*jt+*kt<0) { 22 jt++; 23 } else if(*it+*jt+*kt>0) { 24 kt--; 25 } else { 26 cout<<*it<<" "<<*jt<<" "<<*kt<<endl; 27 flag=1; 28 jt++; 29 kt--; 30 } 31 } 32 } 33 if(!flag) cout<<"No Solution"<<endl; 34 return 0; 35 }
3.数组 + 二分
1 #include <iostream> 2 #include <algorithm> 3 using namespace std; 4 int ans[1005]; 5 int main() { 6 ios::sync_with_stdio(false); 7 int n,flag=0; 8 cin>>n; 9 for(int i=0;i<n;++i) cin>>ans[i]; 10 sort(ans,ans+n); 11 for(int i=0;i<n;++i) { 12 if(ans[i]>=0) break; 13 int j=i+1,k=n-1; 14 while(ans[j]<ans[k]) { 15 if(ans[i]+ans[j]+ans[k]<0) j++; 16 else if(ans[i]+ans[j]+ans[k]>0) k--; 17 else { 18 cout<<ans[i]<<" "<<ans[j]<<" "<<ans[k]<<endl; 19 flag=1; 20 j++; 21 k--; 22 } 23 } 24 } 25 if(!flag) cout<<"No Solution"<<endl; 26 return 0; 27 }