二重循环枚举
#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; }