NEERC2012 Caravan Robbers

Problem C. Caravan Robbers
Input file: caravan.in
Output file: caravan.out
Long long ago in a far far away land there were two great cities and The Great Caravan Road between
them. Many robber gangs “worked” on that road.
By an old custom the i-th band robbed all merchants that dared to travel between ai and bi miles of
The Great Caravan Road. The custom was old, but a clever one, as there were no two distinct i and
j such that ai ≤ aj and bj ≤ bi. Still when intervals controlled by two gangs intersected, bloody fights
erupted occasionally. Gang leaders decided to end those wars. They decided to assign each gang a new
interval such that all new intervals do not intersect (to avoid bloodshed), for each gang their new interval
is subinterval of the old one (to respect the old custom), and all new intervals are of equal length (to
keep things fair).
You are hired to compute the maximal possible length of an interval that each gang would control after
redistribution.
Input
The first line contains n (1 ≤ n ≤ 100 000) — the number of gangs. Each of the next n lines contains
information about one of the gangs — two integer numbers ai and bi (0 ≤ ai < bi ≤ 1 000 000). Data
provided in the input file conforms to the conditions laid out in the problem statement.
Output
Output the maximal possible length of an interval in miles as an irreducible fraction p/q.
Sample input and output
caravan.in caravan.out
3
2 6
1 4
8 12
5/2
In the above example, one possible set of new intervals that each gang would control after redistribution
is given below.
• The first gang would control an interval between 7/2 = 3.5 and 12/2 = 6 miles which has length of
5/2 and is a subinterval of its original (2, 6).
• The second gang would control an interval between 2/2 = 1 and 7/2 = 3.5 miles which has length
of 5/2 and is a subinterval of its original (1, 4).
• The third gang would control an interval between 16/2 = 8 and 21/2 = 10.5 miles which has length

of 5/2 and is a subinterval of its original (8, 12).

这题本身思路很简单,但是答案要求输出分数。如果二分答案的话,得到的是小数。这样看来这题的正解可能不是二分,如果用小数去解答案会不精确。但搜了解题报告发现就是得到小数后,再枚举分母还原回分数就可以了。以后遇到这种输出分数的问题,可以大胆用小数还原回分数一试!

#include<cstdio>
#include<map>
#include<queue>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>
#include<list>
#include<set>
#include<cmath>
using namespace std;
typedef long long LL;
typedef pair<int, int> P;
const int maxn = 1e5 + 7;
const int INF = 1e9;
const double eps = 1e-7;
#define fi first
#define se second

P seg[maxn];
int n;

bool can(double len){
    double pos = 0;
    for(int i = 1;i <= n;i++){
        pos = max(pos, double(seg[i].fi));
        if(pos+len > seg[i].se)
            return false;
        pos += len;
    }
    return true;
}

int main(){
    freopen("caravan.in", "r", stdin);
    freopen("caravan.out", "w", stdout);
    while(scanf("%d", &n) != EOF){
        for(int i = 1;i <= n;i++){
            scanf("%d%d", &seg[i].fi, &seg[i].se);
        }
        sort(seg+1, seg+1+n);
        double l = 0, r = 1e6+5;
        double ans;
        for(int c = 0;c < 100;c++){
            double mid = (l+r)/2;
            if(can(mid)){
                l = mid;
                ans = mid;
            }
            else
                r = mid;
        }
        double Min = 1e9;
        int up, down;
        for(int i = 1;i <= maxn;i++){
            int num = floor(ans*i);
            if(fabs(double(num)/i-ans) < Min){
                Min = fabs(double(num)/i-ans);
                up = num;
                down = i;
            }

            num = ceil(ans*i);
            if(fabs(double(num)/i-ans) < Min){
                Min = fabs(double(num)/i-ans);
                up = num;
                down = i;
            }
        }
        printf("%d/%d\n", up, down);
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值