• 序列相关的趣题 之二


    (4)数组中找到两个数和的绝对值最小 

    像不像2-SUM? 不多解释。主要是绝对值大的动即可。两头扫的方法真好!

    当然要先排序,出去排序就是O(n)。算上排序的话退化到O(nlogn)

    这也是codility上的问题,还没来得及整理。

    上个代码:

    // you can also use includes, for example:
    // #include <algorithm>
    
    #include <algorithm>
    
    int ab(int x) {
        return (x >= 0)?

    x:(-x); } int f(int x,int y) { return ab(x + y); } int solution(vector<int> &A) { // write your code in C++98 vector<int> a = A; sort(a.begin(),a.end()); int answer = f(a[0],a[0]); for (int i = 0, j = a.size() - 1; i <= j; ) { answer = min(answer, f(a[i], a[j])); if (ab(a[i]) > ab(a[j])) { ++i; } else { --j; } } return answer; }


    (5) 给定非负实数数组。已经依照非递减排好序了。

    设数组为C。长度为N,0 ≤ P < Q < N and C[P] * C[Q] ≥ C[P] + C[Q]的下标对数。

    codility上问题是这样定义的C[i] = A[i] + B[i] / 10^6,A是整数部分[0..1000], 而B是分数部分的分子[0..999999] (分数部分的分母统一是1000000)。时间复杂度要O(N)

    这个题事实上就是分析要仔细,再次强调数个数并不一定要枚举。我们无非要计算a * b >= a + b,因为都是正数。再由对称性我们仅仅考虑0<=a<=b的情况。

    考虑较大的数b可能的情形

    (1) b == 0 仅仅有a == 0才符合条件

      (2)   0 < b < 2 无解

      (3) b >= 2 则 b / (b - 1) <= a <= b 


    注意到假设我们由小到大 枚举b, 对条件(3) 那个b / (b - 1) = 1 / (1 - 1 / b)  是单调减小的,所以对更大的b。我们考虑a的时候,之前合法的a也是合法的。这是O(N)的关键,我们仅仅须要记录上一次最后一个合法的a的位置即可。

    上代码:


    // you can use includes, for example:
    // #include <algorithm>
    
    // you can write to stdout for debugging purposes, e.g.
    // cout << "this is a debug message" << endl;
    
    const int M = 1000000000;
    const int W = 1000000;
    
    long long cmp(long long x1,long long y1, long long x2, long long y2) { // x1 / y1 - x2 / y2
        return x1 * y2 - x2 * y1;   
    }
    int solution(vector<int> &A, vector<int> &B) {
        // write your code in C++11
        /*
            let a <= b
            a * b >= a + b
            b == 0 a == 0
            0 < b < 2  no solution
            b >= 2
            b / (b - 1) <= a <= b 
        */
        int n = A.size(), num0 = 0, last = n, answer = 0;
        for (int i = 0; i < n; ++i) {
            if ((A[i] == 0) && (B[i] == 0)) { // b == 0
                answer += num0++;
            }
            else if (A[i] >= 2) { // b >= 2
                if (last >= n) {
                    last = i - 1;
                }
                int x = A[i] * W + B[i], y = x - W;
                for (; (last >= 0) && (cmp(A[last] * W + B[last],W ,x ,y) >= 0); --last)
                ;
                answer += i - 1 - last;
            }
            if (answer >= M) {
                return M;
            }
           // printf("%d %d
    ",i, answer);
            
        }
        return answer;
            
    }




  • 相关阅读:
    python 一
    opengl 正方体+模拟视角旋转
    MFC窗口实现最小化到托盘 右键菜单和还原
    C++获取当前机器内网IP地址
    ubuntu vim终端编辑命令
    整理网站优化(SEO)的方案
    c++函数声明的位置对函数重载的影响
    lua调用dll demo
    一、智能指针及线程同步总结------linux多线程服务端编程
    vscode remote wsl 的NoPermissions permission denied问题
  • 原文地址:https://www.cnblogs.com/bhlsheji/p/5159552.html
Copyright © 2020-2023  润新知