#1692 : 第K小分数

时间限制:10000ms
单点时限:1000ms
内存限制:256MB

描述

给定N个不同的质数P1, P2, … PN。用它们作为分目可以组成(P1-1) + (P2-1) + … (PN-1)个分数:

1/P1, 2/P1, 3/P1, …, P1-1/P1, 1/P2, 2/P2, 3/P2, … P2-1/P2, … 1/PN, 2/PN, … PN-1/PN

请帮助小Ho求出其中第K小的分数。
输入

第一行包含两个整数N和L。

以下N行每行包含一个质数Pi。

对于70%的数据,1 ≤ N ≤ 100, 1 ≤ K ≤ 1000000, 2 ≤ Pi ≤ 100000

对于100%的数据, 1 ≤ N ≤ 1000, 1 ≤ K ≤ 1000000000, 2 ≤ Pi ≤ 1000000000
输出

输出一个分数表示答案
样例输入

3 4  
2  
3  
5

样例输出

1/2

思路:每个质数对应的分数为一个集合,然后扫描集合时二分,同时按比例选定对应集合分数(p[0~n-1]均为质数,故小于主集合i最大选定分数)个数,从而当选定分数个数为k时,主集合i选定的最大分数即为第k小值

#include <iostream>
#include <cstdio>

using namespace std;

typedef long long ll;
const int maxn = 1005;
int n,k;
int p[maxn];

void Read(){
    scanf("%d%d",&n,&k);
    int i;
    for(i=0;i<n;i++)
        scanf("%d",&p[i]);
}

ll Check(int x, int pos){
    int i;
    ll sum = 0;
    for(i=0;i<n;i++){
        sum += (ll)x*p[i]/p[pos];
    }
    return sum;
}

void Solve(){
    int low,mid,high,i;
    for(i=0;i<n;i++){
        low = 1;
        high = p[i]-1;
        while(low<high){
            mid = (low+high)>>1; //(>>1 <=> /2)
            if(Check(mid,i) >= k) high = mid;
            else low = mid+1;
        }
        if(Check(high,i) == k){
            printf("%d/%d\n",high,p[i]);
            break; //QAQ    
        }
    }
}

int main(){
//  freopen("Data.txt","r",stdin);  
    Read();
    Solve();
    return 0;
}

参照:(http://hihocoder.com/contest/offers46/solution/1266069)

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值