1. 程式人生 > >51nod 1090 3個數和為0【二分】

51nod 1090 3個數和為0【二分】

c++ 一個 pan == turn its ane mage i++

1090 3個數和為0技術分享 基準時間限制:1 秒 空間限制:131072 KB 分值: 5 難度:1級算法題 技術分享 收藏 技術分享 關註 給出一個長度為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

【分析】:直接枚舉兩個數,二分查找第三個數就行了。由於題中要求按數的大小排序輸出,所以直接sort升序輸出即可,這樣即可用二分查找第三個數,即-a[i]-a[j],並且一定比a[i]和a[j]大,復雜度為n^2log(n);
【代碼】:
技術分享
#include <bits/stdc++.h>

using namespace std;

const int maxn = 1000+10;
int n;
int a[maxn];

int check(int x) { int l=0,r=n-1; while(l<=r) { int mid=(l+r)>>1; if(a[mid]==x) return 1; if(a[mid]<x) l=mid+1; else r=mid-1; } return 0; } int main() { int ans; int flag=0; cin
>>n; for(int i=0;i<n;i++) cin>>a[i]; sort(a,a+n); for(int i=0;i<n;i++) { for(int j=i+1;j<n;j++) { int ans=-a[i]-a[j]; if(ans<=a[j]) break; if(check(ans)) { cout<<a[i]<<" "<<a[j]<<" "<<ans<<endl; flag=1; } } } if(!flag) cout<<"No Solution"<<endl; return 0; }
二分

技術分享
#include <bits/stdc++.h>

using namespace std;
const int maxn = 1000+10;
int main()
{
    int n;
    int flag=1;
    int a[maxn];
    cin>>n;
    for(int i=0;i<n;i++)
        cin>>a[i];
    sort(a,a+n);
    for(int i=0;i<n;i++)
    {
        for(int j=i+1;j<n;j++)
        {
            if(a[i]+a[j]<=0)
            {
                for(int k=j+1;k<n;k++)
                {
                    if(a[i]+a[j]+a[k]==0)
                    {
                        cout<<a[i]<<" "<<a[j]<<" "<<a[k]<<endl;
                        flag=0;
                    }
                }
            }
        }
    }
    if(flag)
        cout<<"No Solution"<<endl;
    return 0;
}
暴力枚舉+剪枝

51nod 1090 3個數和為0【二分】