A sorted list A
contains 1, plus some number of primes. Then, for every p < q in the list, we consider the fraction p/q.
What is the K
-th smallest fraction considered? Return your answer as an array of ints, where answer[0] = p
and answer[1] = q
.
Examples: Input: A = [1, 2, 3, 5], K = 3 Output: [2, 5] Explanation: The fractions to be considered in sorted order are: 1/5, 1/3, 2/5, 1/2, 3/5, 2/3. The third fraction is 2/5. Input: A = [1, 7], K = 1 Output: [1, 7]
Note:
A
will have length between2
and2000
.- Each
A[i]
will be between1
and30000
. K
will be between1
andA.length * (A.length - 1) / 2
.
思路:看数字范围,平方排序不是一个好办法,极有可能会超时。然后要求第K小,这是可以用一个有限队列存储,为了节省时间,没必要存储平方个节点,因为处理起来就是平方级别的,观察这个升序数组(题目第一句话),我们可以发现最小的肯定是第一个元素除以最后一个元素,第二小的可能是第二个元素除以最后一个元素,也可能是第一个元素除以倒数第二个元素,这是我们可以声明一个结构体【i,j,A[i]/A[j]】,声明一个优先队列,初始时将吗每一个【0,j,A[0]/A[j]】(0=<j<sz)放入队列中,以后每一次取A[i]/A[j]的最小值,即队列对第三个维度进行最小排序,每次取出队首的,然后把【i+1,j,A[i+1]/A[j]】放进去,重复k-1次后,队首元素就是我们要找的。
代码如下:
/*by kzl*/
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<queue>
#include<stack>
#include<vector>
#include<map>
using namespace std;
const int maxx = 1e5;
const int INF = 0x3f3f3f3f;
const int mod = 1e9+7;
typedef long long LL;
struct My{//复制代码时注意结构体也要带进去
int x,y;
double ans;
My(){}
My(int a,int b,double c):x(a),y(b),ans(c){}
bool operator < (const My &m)const{
return ans>m.ans;
}
};
vector<int> kthSmallestPrimeFraction(vector<int>& A, int K) {
priority_queue<My>p;
int sz = A.size();
for(int i=0;i<sz;i++){
p.push(My(0,i,1.0*A[0]/A[i]));
}
K--;
while(K--){
My m = p.top();
p.pop();
//cout<<m.x<<" "<<m.y<<" "<<m.ans<<endl;
p.push(My(m.x+1,m.y,1.0*A[m.x+1]/A[m.y]));
}
My m = p.top();
vector<int>ve;
ve.push_back(A[m.x]);
ve.push_back(A[m.y]);
return ve;
}
int main(){
int n,a,k;
cin>>n;
vector<int>ve;
for(int i=0;i<n;i++){
cin>>a;
ve.push_back(a);
}
cin>>k;
vector<int>v = kthSmallestPrimeFraction(ve,k);
cout<<v[0]<<" "<<v[1]<<endl;
return 0;
}