题目地址
https://www.patest.cn/contests/pat-a-practise/1085
题目描述
Given a sequence of positive integers and another positive integer p. The sequence is said to be a “perfect sequence” if M <= m * p where M and m are the maximum and minimum numbers in the sequence, respectively.
Now given a sequence and a parameter p, you are supposed to find from the sequence as many numbers as possible to form a perfect subsequence.
Input Specification:
Each input file contains one test case. For each case, the first line contains two positive integers N and p, where N (<= 105) is the number of integers in the sequence, and p (<= 109) is the parameter. In the second line there are N positive integers, each is no greater than 109 .
Output Specification:
For each test case, print in one line the maximum number of integers that can be chosen to form a perfect subsequence.
Sample Input:
10 8
2 3 20 4 5 1 6 7 8 9
Sample Output:
8
ac代码(二分法思路)
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <iostream>
#include <string>
#include <vector>
#include <queue>
#include <algorithm>
#include <sstream>
#include <list>
#include <stack>
#include <map>
#include <set>
#include <iterator>
using namespace std;
// freopen("in.txt", "r", stdin);
#define INF 0x7fffffff
typedef long long int LL;
LL n, p;
vector<LL> v;
// 找到第一个大于val的数 返回下标
int bsearch(int left, int right ,LL val)
{
if(left > right)
return -1;
if(val > v[right])
return right + 1;
if(val < v[left])
return -1;
int tmpL = left;
int tmpR = right;
while(left < right) // left == right 将退出
{
int mid = (right - left) / 2 + left;
if(val == v[mid])
{
int j = mid;
while(v[j] <= val)
j ++;
return j; // 第一个大于 val的数的下标
}else if(val > v[mid])
{
left = mid + 1;
}else{
right = mid - 1;
}
}
int j = min(left, right);
int k;
for(k = j ; j < tmpR;j ++)
{
if(v[j] > val)
{
break;
}
}
return k;
}
int main( )
{
//freopen("in.txt","r",stdin);
while(scanf("%lld%lld", &n, &p) != EOF)
{
v.resize(n);
for(int i=0;i<n;i++)
{
scanf("%lld", &v[i]);
}
sort(v.begin(), v.end());
int l = 0;
int r = n - 1;
if(v[r] <= v[l] * p)
{
printf("%d\n", n);
}else{
int maxLen = 1;
for(int i=0;i<n-1;i++)
{
LL val = v[i] * p; //
int t = bsearch(i + 1, n-1 , val);
if(t != -1)
{
if(t - i > maxLen)
{
maxLen = t - i;
}
}
}
printf("%d\n", maxLen);
}
}
return 0;
}
超时代码
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <iostream>
#include <string>
#include <vector>
#include <queue>
#include <algorithm>
#include <sstream>
#include <list>
#include <stack>
#include <map>
#include <set>
#include <iterator>
using namespace std;
// freopen("in.txt", "r", stdin);
#define INF 0x7fffffff
typedef long long int LL;
LL n, p;
vector<LL> v;
int main( )
{
//freopen("in.txt","r",stdin);
while(scanf("%lld%lld", &n, &p) != EOF)
{
v.resize(n);
for(int i=0;i<n;i++)
{
scanf("%lld", &v[i]);
}
sort(v.begin(), v.end());
int l = 0;
int r = n - 1;
if(v[r] <= v[l] * p)
{
printf("%lld\n", n);
}else{
int maxLen = -1;
for(int i=0;i<n-1;i++)
{
if(n - 1 - i + 1 < maxLen)
break;
int cnt = 1;
for(int j = i+1;j < n;j++)
{
if(v[j] <= v[i] * p)
{
cnt ++;
}
}
if(cnt > maxLen)
{
maxLen = cnt;
}
}
printf("%d\n", maxLen);
}
}
return 0;
}