题目分析:
意思是要求对于一个给出的数组,我们在其中尽可能多选数字,使得所选数字的max <= min * p,而由于数据量较大直接二层循环不加优化实现是不现实的,由题意得知,对于数字序列的子序列选择没有连续性要求,就是可以随便选的意思,所以我们先将整个序列从小到大排序(这样在遍历时j-i+1就是你选择的个数),从第i == 1个元素开始往后搜索,只要能满足max <= min * p就继续搜索,直到不满足的退出,而在i+1个元素开始搜索时我们发现,由于下标为i+1的元素一定比i大(从小到大排序),所以之前i元素能达到的最远max,i+1元素是必然能达到的,所以i+1元素开始的位置就是i元素的最右极限+1(我用cnt记录i元素本次搜索能达到的最远的下标,i+1从cnt+1开始搜索)
本题代码:
1 #include<iostream> 2 #include<stdio.h> 3 #include<algorithm> 4 using namespace std; 5 6 const int N = 100005; 7 int k[N]; 8 int n, p, ans; 9 10 int main(){ 11 scanf("%d%d", &n, &p); 12 for(int i = 1; i <= n; i++) scanf("%d", &k[i]); 13 sort(k+1, k+n+1); 14 ans = 0; 15 int cnt = 0; 16 for(int i = 1; i <= n; i++){ 17 if(n - i + 1 > ans){ 18 for(int j = cnt+1; j <= n; j++){ 19 if(k[j] <= p * k[i]){ 20 cnt++; 21 j-i+1 > ans ? ans = j-i+1 : ans; 22 }else break; 23 } 24 }else break; 25 } 26 printf("%d ", ans); 27 return 0; 28 }