1085. Perfect Sequence (25)

题目地址: http://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 <stdio.h>
#include <iostream> 
#include <stdlib.h>
#include <string>
#include <string.h>
#include <algorithm>
#include <math.h>
#include <map>
#include <unordered_map>
#include <queue>
#include <vector>
#include <set>
#include <iterator>

using namespace std;

#define N 100001

int nn;
long int  p;
long int a[N];

bool cmp(long int x, long int y)
{
    return x < y;
}

int bsearch(int left, int right, long int n)
{
    if (n >= a[right])//里面这里判断一下可以
        return right;
    while (left <= right)
    {
        int mid = (left + right) / 2;
        if (a[mid] == n)
        {
            while (a[mid] == n)//这里相等 后不断的while == n
            {
                mid++;
                if (mid > right)
                    return right;
            }
            return mid - 1; 
        }
        else if (a[mid] < n)
        {
            if (a[mid + 1] > n) //这里是大于
            {
                return mid;
            }
            left = mid + 1;
        }
        else{
            if (a[mid - 1] <= n) // 这里是小于等于
            {
                return mid - 1;
            }
            right = mid - 1;
        }
    }
}

int main()
{
    //freopen("in", "r", stdin);
    scanf("%ld%ld", &nn, &p);
    int i, j;
    for (i = 0; i < nn; i++)
    {
        scanf("%ld", &a[i]);
    }
    sort(a, a + nn, cmp);

    int maxLen = 0;
    for (i = 0; i < nn; i++)
    {
        long int m = a[i];
        if (nn - i < maxLen) // 这里可以判断一下 nn - i 
            break;
        int tmpL = 0;
        long int M = m * p;
        int pos = bsearch(i, nn - 1, M);
        tmpL = pos - i + 1;
        if (tmpL > maxLen)
        {
            maxLen = tmpL;
        }
    }

    printf("%d\n", maxLen);
    return 0;
}

ac代码二:需要加一个delta 优化

#include <stdio.h>
#include <iostream> 
#include <stdlib.h>
#include <string>
#include <string.h>
#include <algorithm>
#include <math.h>
#include <map>
#include <unordered_map>
#include <queue>
#include <vector>
#include <set>
#include <iterator>

using namespace std;

#define N 100001

int nn;
long int  p;
long int a[N];

bool cmp(long  int x, long int y)
{
  return x < y;
}

int main()
{
  // freopen("in", "r", stdin);
  scanf("%ld%ld", &nn, &p);
  int i, j;
  for (i = 0; i < nn; i++)
  {
    scanf("%ld", &a[i]);
  }
  sort(a, a + nn, cmp);
  int delta = 0;
  int maxLen = 0;
  for (i = 0; i < nn; i++)
  {
    if (nn - i + 1 < maxLen)
      break;
    int m = a[i];
    int tmpL = 0;
    // 这里是 i+delta - 1 不是 i+delta,自己做的时候搞错了,然后画了下,发现这个位置自己写错了
    for (j = i+delta-1; j <= nn - 1; j++)
    {
      int M = a[j];
      if (M > m * p)
      {
        tmpL = j - i;
        break;
      }
    }
    if (j == nn) // 这里到头了判断下
      tmpL = nn - i;
    if (tmpL > maxLen)
    {
      maxLen = tmpL;
      delta = maxLen;
    }
  }

  printf("%d\n", maxLen);
  return 0;
}

你可能感兴趣的:(二分查找)