给定一个正整数数列,和正整数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
我似乎又用了一个麻烦的方法,当然我这个方法比二重循环找要快多了,主要用了二分查找找到<=M*P的最大值的位置
其实我看到了一个超简单的方法,先从排好序的数据中的第一个数找数列长,之后的数就在这个数列长的基础上找,也不慢
见:http://blog.youkuaiyun.com/wyxdexyq/article/details/40372833,主要是代码短,感觉很帅。相比之下我这个这么长,我深深的感到我的思维还是不够跳
#include <stdio.h> #include <stdlib.h> #include <algorithm> using namespace std; int findmax (long long numList[], int size, long long maxnum) { int left=0, right=size-1; int middle = (left+right)/2; if(maxnum >= numList[size-1]) return size-1; while(left < right) { if(numList[middle] == maxnum) return middle; else if(numList[middle] < maxnum) left = middle+1; else right = middle-1; middle = (left+right)/2; } if(numList[left] == maxnum) return left; else return left-1; } int main() { int n, p; scanf("%d %d", &n, &p); long long *numList = (long long *) malloc (n * sizeof(long long)); int i; for(i = 0; i < n; i++) scanf("%lld", &numList[i]); sort(numList, numList+n); int seqlength, maxlength=0; int maxposition; for(i = 0; i < n; i++) { maxposition = findmax(numList, n, numList[i]*p); seqlength = maxposition - i + 1; if(maxlength < seqlength) maxlength = seqlength; if(maxposition == n - 1) break; } printf("%d\n", maxlength); return 0; }