2016-2017 ACM-ICPC, NEERC, Southern Subregional Contest G. Car Repair Shop(优先队列)

链接:http://codeforces.com/contest/730/problem/G

G. Car Repair Shop
time limit per test
2 seconds
memory limit per test
512 megabytes
input
standard input
output
standard output

Polycarp starts his own business. Tomorrow will be the first working day of his car repair shop. For now the car repair shop is very small and only one car can be repaired at a given time.

Polycarp is good at marketing, so he has already collected n requests from clients. The requests are numbered from 1 to n in order they came.

The i-th request is characterized by two values:si — the day when a client wants to start the repair of his car,di — duration (in days) to repair the car. The days are enumerated from 1, the first day is tomorrow, the second day is the day after tomorrow and so on.

Polycarp is making schedule by processing requests in the order from the first to then-th request. He schedules thei-th request as follows:

  • If the car repair shop is idle for di days starting fromsi (si, si + 1, ..., si + di - 1), then these days are used to repair a car of the i-th client.
  • Otherwise, Polycarp finds the first day x (from 1 and further) that there aredi subsequent days when no repair is scheduled starting fromx. In other words he chooses the smallest positivex that all daysx, x + 1, ..., x + di - 1 are not scheduled for repair of any car. So, the car of thei-th client will be repaired in the range[x, x + di - 1]. It is possible that the dayx when repair is scheduled to start will be less thansi.

Given n requests, you are asked to help Polycarp schedule all of them according to the rules above.

Input

The first line contains integer n (1 ≤ n ≤ 200) — the number of requests from clients.

The following n lines contain requests, one request per line. Thei-th request is given as the pair of integerssi, di (1 ≤ si ≤ 109,1 ≤ di ≤ 5·106), wheresi is the preferred time to start repairing thei-th car,di is the number of days to repair thei-th car.

The requests should be processed in the order they are given in the input.

Output

Print n lines. The i-th line should contain two integers — the start day to repair thei-th car and the finish day to repair thei-th car.

Examples
Input
3
9 2
7 3
2 4
Output
9 10
1 3
4 7
Input
4
1000000000 1000000
1000000000 1000000
100000000 1000000
1000000000 1000000
Output
1000000000 1000999999
1 1000000
100000000 100999999
1000001 2000000
题意:Polycarp要修汽n辆车,每次只能修一辆,每辆车有要求开始修理的时间si,修理需要的时间是di。现在安排修车计划,能在要求时间si修的车按照si时间修,否则便尽量往前安排,时间从1开始。
思路:1<=si<=10的9次方->离散化?修车区间、往前安排->线段树?二分? codeforces重现的时候胡思乱想,结果发现处理得都比较麻烦,后来想到用优先队列处理,
队列保存空闲区间,安照区间左边界从小到大排,每次按要求找符合的区间,找到了就拿出来,把这个区间用完后剩余的两段区间再放回队列,如果没找到符合要求的区间,那就从最前的区间开始找,找区间长度满足的区间,一样再分解。队列只保留空闲区间,这样离散化,排序都实现了,因为数据并不大,所以可以实现。
#include <bits/stdc++.h>
using namespace std;
#define ll long long int
const ll inf = 2000000000;
struct node{
    ll l, r;
    bool operator < (const node &a) const {
        return l>a.l;//最小值优先
    }
};
ll ans[205][2];
priority_queue<node> q;
priority_queue<node> p;
int main()
{
    int n, i;
    ll s, d;
    scanf("%d", &n);
    node f;
    f.l = 1;
    f.r = inf;
    q.push(f);
    for(i = 0;i < n;i++){
        scanf("%I64d %I64d", &s, &d);
        bool flag = 0;
        while(!q.empty()){
            node now = q.top();
            q.pop();
            //printf("%I64d %I64d\n", now.l, now.r);
            if(now.l <=s&&now.r>=s+d-1){
                node a, b;
                //printf("--\n");
                ans[i][0] = s, ans[i][1] = s+d-1;
                a.l = now.l, a.r = s-1;
                b.l = s+d, b.r = now.r;
                if(a.l<=a.r) q.push(a);
                if(b.l<=b.r) q.push(b);
                flag = 1;
                break;
            }
            p.push(now);
        }
        if(!flag){
            while(!p.empty()){
                node now = p.top();
                p.pop();
                if(now.r-now.l+1>=d){
                    node a;
                    //printf("--\n");
                    ans[i][0] = now.l, ans[i][1] = now.l+d-1;
                    a.l = now.l+d, a.r = now.r;
                    if(a.l<=a.r) q.push(a);
                    break;
                }
                q.push(now);

            }
        }
        while(!p.empty()){
            node now = p.top();
            q.push(now);
            p.pop();
        }
    }
    for(i = 0;i < n;i++) printf("%I64d %I64d\n", ans[i][0], ans[i][1]);
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值