PAT.完美数列(标程:二分)
题目描述
给定一个正整数数列,和正整数p,设这个数列中的最大值是M,最小值是m,如果M <= m * p,则称这个数列是完美数列。
现在给定参数p和一些正整数,请你从中选择尽可能多的数构成一个完美数列。
输入描述:
输入第一行给出两个正整数N和p,其中N(<= 105)是输入的正整数的个数,p(<= 109)是给定的参数。第二行给出N个正整数,每个数
不超过109。
输出描述:
在一行中输出最多可以选择多少个数可以用它们组成一个完美数列。
输入例子:
10 8
2 3 20 4 5 1 6 7 8 9
输出例子:
8
/* 读题之后发现类似于贪心的题目,先把数字从小到大排序,然后对于每个数字i,在他前面找到一个数num ,num是满足k * num < i的最大坐标,然后i的坐标减去num的坐标就是那个数字匹配到的最长数列。 复杂度O(nlgn)。 */ #include <iostream> #include <algorithm> #define mid ((l + r) >> 1) using namespace std; const int maxn = 1e5 + 5; int n, k, ans; int num[maxn]; int _find(int l, int r, int x) { while(l <= r) { if(k * num[mid] >= x) { r = mid - 1; } else { l = mid + 1; } } return r; } int main() { ans = 0; cin >> n >> k; for(int i = 0; i < n; i ++) { cin >> num[i]; } sort(num, num + n); for(int i = n - 1; i > 0; i --) { ans = max(ans, i - _find(0, i, num[i])); } cout << ans << endl; return 0; }
时间并不会因为你的迷茫和迟疑而停留,就在你看这篇文章的同时,不知道有多少人在冥思苦想,在为算法废寝忘食,不知道有多少人在狂热地拍着代码,不知道又有多少提交一遍又一遍地刷新着OJ的status页面……
没有谁生来就是神牛,而千里之行,始于足下!