• 算法初步——二分 + two pointers B1030/A1085完美数列 (使用upper_bound函数 和 自己构建二分函数 )


    二重循环枚举

    #include <bits/stdc++.h>
    #include<math.h>
    #include <string>
    using namespace std;
    const int MAX_LEN = 100005;
    bool cmp(int a,int b){
        return a<b;
    }
    int main(){
        int n;
        cin>>n;
        int temp[n];
        for(int i=0;i<n;++i){
            temp[i] = 0;
        }
        int p;
        //cin>>n;
        cin>>p;
        for(int i=0;i<n;++i){
            cin>>temp[i];
        }
        sort(temp,temp+n,cmp);
        int result[n];
        for(int i=0;i<n;++i){
            result[i] = n-i;
            /*for(int j=n-1;j>=0 && j>=i;--j){
                if(temp[i] * p > temp[j]){
                    result[i]--;
                }
            }*/
            for(int j=i;j<n;++j){
                if(temp[i] * p >= temp[j]){
                    continue;
                }else{
                    result[i]--;
                }
            }
        }
        int max = 0;
        for(int i =0;i<n;++i){
            if(result[i] > max){
                max = result[i];
            }
        }
        cout<<max<<endl;
        //sort(result,result+n,cmp);
        //cout<<result[n-1]<<endl;
        /*int count = n-1;
        for(int i =n-1;i>=0;--i){
            if(temp[0] * p < temp[i]){
                count--;
            }
        }
        cout<<count+1<<endl;*/
        //int count = 0;
        /*for(int i =0;i<n;++i){
            for(int j=n-1;j>=0;--j){
                if(temp[i] * p < temp[j]){
                    count
                }
            }
        }*/
        system("pause");
        return 0;
    } 

    最后一个错误用例,原因是 temp[i] * p 有可能超过 int 范围,应该用 long long 型存储!

    如果强制进行O(n平方)的二重循环枚举,那么根据题目的数据范围,肯定会超时的。这里有两种方法来解决这个问题。

    二分查找和 two pointers。

    解法1:

    二分查找(自己构建二分函数)

    #include <bits/stdc++.h>
    #include<math.h>
    #include <string>
    using namespace std;
    const int MAX_LEN = 100005;
    bool cmp(int a,int b){
        return a<b;
    }
    int n,p,a[MAX_LEN];
    int binarySearch(int i,long long x){
        if(a[n-1] <= x) return n;
        int l = i+1,r = n-1,mid;
        while(l < r){
            mid = (l+r)/2;
            if(a[mid] <= x){
                l = mid + 1;
            }else{
                r = mid;
            }
        }
        return l;
    }
    int main(){
        scanf("%d%d",&n,&p);
        for(int i =0;i<n;++i){
            scanf("%d",&a[i]);
        }
        sort(a,a+n);//递增顺序
        int ans = 1;//最大长度,初值为1
        for(int i =0;i<n;++i){
            //在a[i+1]-a[n-1]中查找第一个超过a[i]*p的数,返回其位置给j
            int j = binarySearch(i,(long long)a[i] * p);
            ans = max(ans,j-i);
        }
        cout<<ans<<endl;
        system("pause");
        return 0;
    } 

    (2)使用upper_bound函数

    #include <bits/stdc++.h>
    #include<math.h>
    #include <string>
    using namespace std;
    const int MAX_LEN = 100005;
    bool cmp(int a,int b){
        return a<b;
    }
    int n,p,a[MAX_LEN];
    int main(){
        scanf("%d%d",&n,&p);
        for(int i =0;i<n;++i){
            scanf("%d",&a[i]);
        }
        sort(a,a+n);//递增顺序
        int ans = 1;//最大长度,初值为1
        for(int i =0;i<n;++i){
            //在a[i+1]-a[n-1]中查找第一个超过a[i]*p的数,返回其位置给j
            int j = upper_bound(a+i+1,a+n,(long long)a[i] * p) - a;
            ans = max(ans,j-i);
        }
        cout<<ans<<endl;
        system("pause");
        return 0;
    } 

    two pointers 解法:

    #include <bits/stdc++.h>
    #include<math.h>
    #include <string>
    using namespace std;
    const int MAX_LEN = 100005;
    /*bool cmp(int a,int b){
        return a<b;
    }*/
    int n,p,a[MAX_LEN];
    int main(){
        scanf("%d%d",&n,&p);
        for(int i =0;i<n;++i){
            scanf("%d",&a[i]);
        }
        sort(a,a+n);//递增顺序
        int i = 0,j=0,count = 1;
        while(i<n && j<n){
            //j不断右移,直到恰好不满足条件
            while(j < n && a[j] <= (long long)a[i] * p){
                count = max(count,j - i + 1);//更新计数器count
                j++; 
            }
            i++;//i右移一位 
        }
        cout<<count<<endl; 
        system("pause");
        return 0;
    } 
  • 相关阅读:
    设置靠近 水平居中的主体内容Div 的 左侧位置固定的Div
    [转]jQuery页面滚动图片等元素动态加载实现
    [转]LazyLoad.js及scrollLoading.js
    [转]jquery 鼠标放在图片上显示图片的放大镜效果jqzoom_ev-2.3
    [转]java处理高并发高负载类网站的优化方法
    spring-session之二:简单配置
    spring-session之一:简介、使用及实现原理
    UDP协议详解
    Netty Client 重连实现
    netty中的UDP
  • 原文地址:https://www.cnblogs.com/JasonPeng1/p/12185714.html
Copyright © 2020-2023  润新知