(有意思的水题)51nod-1090-

点击打开题目链接

给出一个长度为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

其实是很水的一道题,

但是至一道题却是能启发思路,通过不同的思想,能一步步的优化,这就是算法的魅力啊~~~!

直接暴力O(n^3)也能过

    for (int i = 0; i < n-2; i++)
    {
        if(a[i] > 0)
            break;
        for (int j = i+1; j < n-1;j++)
        {
            for(int k = j+1; k < n;k++)
            {
                if(a[i]+a[j]+a[k] == 0)
                {
                    flag = 1;
                    cout << a[i] << " " << a[j] << " " << a[k] << endl;
                }
            }
        } 
    }

用二分去查找第三个数,这样会快点 O(n^2 logn),这里自己写了二分函数

/*************
 * 
 * 二分搜索,O(n^2logn)
 * 确定两个数,二分查找第三个数
 ***************/

#include <iostream>
#include <algorithm>

using namespace std;

const int MAXL = 1005;

int a[MAXL];

bool binary_find(int L, int R, int x)
{
    while (L < R)
    {
        int M = (L + R) >> 1;
        if (a[M] == x)
            return true;
        else if (a[M] > x)
            R = M;
        else
            L = M + 1;
    }
    return false;
}

int main()
{
    ios::sync_with_stdio(false);
    bool flag = true;
    int n;
    cin >> n;
    for (int i = 0; i < n; i++)
    {
        cin >> a[i];
    }
    sort(a, a + n);
    for (int i = 0; i < n - 2; i++)
    {
        if (a[i] > 0)
            break;
        for (int j = i + 1; j < n - 1; j++)
        {
            int x = (a[i] + a[j]);
            if (x > 0)
                break;
            x = -1 * x;
            if (binary_find(j + 1, n, x))
            {
                flag = false;
                cout << a[i] << " " << a[j] << " " << x << endl;
            }
        }
    }
    if (flag)
        cout << "No Solution" << endl;
    system("pause");
    return 0;
}

在网上看了一个更优化的解救方案,同时查找两个数,O(n^2),优秀啊,

/***************
 * 
 * 更优的时间-同时搜索两个数
 * 
 ***************/

#include <iostream>
#include <cstdio>
#include <algorithm>

using namespace std;

const int MAXN = 1005;
int a[MAXN];

int main()
{
    ios::sync_with_stdio(false);
    bool flag = true;
    int n;
    cin >> n;
    for (int i = 0; i < n; i++)
        cin >> a[i];
    sort(a, a + n);
    for (int i = 0; i < n; i++)
    {
        int L, R;
        L = i + 1;
        R = n - 1;
        while (L < R)
        {
            int sum = a[i] + a[L] + a[R];
            if (sum == 0)
            {
                cout << a[i] << " " << a[L] << " " << a[R] << endl;
                L++;
                R--;
                flag = false;
            }
            else if (sum > 0)
                R--;
            else if (sum < 0)
                L++;
        }
    }
    if (flag)
        cout << "No Solution" << endl;
    // system("pause");
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值