zoukankan      html  css  js  c++  java
  • 算法初步——二分 + 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;
    } 
  • 相关阅读:
    ContentControl 嵌套后 Foreground 无法继承
    Windows Phone 开发学习
    Windows 8 Metro 风格应用开发
    微信小程序中时间戳和日期的相互转换
    二维数组,要求按考试分数高到低排序,如果考试分数相同就按违纪扣分低到高排序
    微信小程序实现按首字母检索城市列表
    微信40125错误
    sublime text3 英文版转为中文版
    html5代码如何转成小程序代码
    阿里云刘强:无影云电脑构建云上安全办公室
  • 原文地址:https://www.cnblogs.com/JasonPeng1/p/12185714.html
Copyright © 2011-2022 走看看