9および問題の演習溶液を与えられた数の半分

タイトル説明

これは、与えられた数の数字の組と等しいがあるかどうかを尋ねる、整数の数を示します。

入力形式

合計三行:
最初の行は整数である\(N-(0 \ N-LT \ 100000ルは)\) 表現\(N- \)整数。
2行目は、N個の整数です。範囲内の整数であり、\(0 \)する\(10 ^ 8 \)との間で。
第三のラインは、整数である(LE M \ル2 ^ {30})\ \ M(0)\、および必要性を表明しました。

出力フォーマット

現在、mは出力二つの整数、小さな正面の数であれば、大後、単一のスペースで区切られました。複数の条件の数が満たされている場合、より小さな選択の少ない数の数。数は、出力ライン「NO」の要件を満たすために見つけることができない場合。

サンプル入力

4
2 5 1 4
6

サンプル出力

1 5

トピック分析

この質問は、時間計算量使用することができます\(O(N)\)ダブルポインタ方式のを。(興味のある学生は見つけることができます)
が、我々は説明するためにここに来る\(O(nlogn)\) 2つの分解を。
配列の場合は\(A_1、A_2、...、 A_N \) 、最初の事は、私たちが使用する必要がsort昇順にそれらを与えるために機能を。
その後、我々はから缶\(1 \)\(\ N-)横座標\(Iは\) のための\([i]が\) 我々はでき\([I + 1、N ] \) このバイナリ要素と同じであるがあるかどうかを見つけるために、間隔範囲を使用\(ミリアンペア[I]が\)
私たちが保証しなければならないとき、もちろん多少、我々は通過\([I] \ルメートル/ 2 \) 私は別の要素のバイナリ検索していますので、その上に、確かにある(\ルA [i]が\)\
次のようにコードは次のとおりです。

#include <bits/stdc++.h>
using namespace std;
const int maxn = 100010;
int n, m, a[maxn];
// check函数用于二分查找数组a[L,R]中是否存在值为num的元素
bool check(int num, int L, int R) {
    while (L <= R) {
        int mid = (L + R) / 2;
        if (a[mid] == num) return true;
        else if (a[mid] > num) R = mid - 1;
        else L = mid + 1;
    }
    return false;
}
int main() {
    cin >> n;
    for (int i = 1; i <= n; i ++) cin >> a[i];
    cin >> m;
    sort(a+1, a+1+n);   // 给数组a[1]到a[n]范围内的数从小到大排序
    for (int i = 1; i <= n && a[i] <= m/2; i ++) { // 开始遍历a[i]
        if (check(m - a[i], i+1, n)) {  // 对[i+1,n]区间范围内二分查找m-a[i]
            cout << a[i] << " " << m-a[i] << endl;
            return 0;
        }
    }
    puts("NO");
    return 0;
}

おすすめ

転載: www.cnblogs.com/zifeiynoip/p/11450637.html