CodeForces 253E Printer

题目链接


题意:有N份文件需要打印,每行输入该文件传入时间第ti秒,需要打印的时间si秒,和打印优先级pi。每一秒打印机都打印优先级最高的文件,传入的N份文件中有一份优先级为-1代表未知。已知那份优先级未知的文件打印结束的时间为T,求优先级未知的文件的优先级可以为多少,按顺序输出每份文件打印结束的时间。

题解:二分文件的优先级,判断是否成立,最后按输入顺序输出。



#include<stdio.h>
#include<queue>
#include<cstring>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<assert.h>
#include<stdlib.h>
#include<time.h>
#include<stack>
#include<vector>
#include<map>
#include<set>
#include<fstream>
#define pi acos(-1.0)
#define INF 1000000000
#define debug printf("---------------\n");
using namespace std;

struct Work
{
    int st;
    int v;
    int yu;
    int num;
    friend bool operator < (Work a,Work b)
    {
        return a.yu<b.yu;
    }
} w[50005];


bool cmp1(Work a,Work b)
{
    if(a.st==b.st)
    {
        return a.yu>b.yu;
    }
    return a.st<b.st;
}
int n;
priority_queue<Work>q;
int check(int p,long long k)
{
    //printf("p=%d k=%I64d\n",p,k);
    Work tt;
    while(!q.empty())
    {
        q.pop();
    }
    long long t=0;
    for(int i=0; i<n; i++)
    {
        while(!q.empty()&&q.top().v<=w[i].st-t)
        {
            t+=q.top().v;
            if(q.top().yu==p)
            {
                if(t==k)
                {
                    return 0;
                }
                else if(t<k)
                {
                    return -1;
                }
                else
                {
                    //debug
                    return 1;
                }
            }
            q.pop();
        }
        if(q.empty())
        {
            tt=w[i];
            if(tt.yu==-1)
            {
                tt.yu=p;
            }
            q.push(tt);
            t=tt.st;
        }
        else if(w[i].st-t<q.top().v)
        {
            tt=q.top();
            q.pop();
            tt.v-=w[i].st-t;
            q.push(tt);
            tt=w[i];
            if(tt.yu==-1)
            {
                tt.yu=p;
            }
            q.push(tt);
            t=tt.st;
        }
    }
    //printf("size=%d\n",q.size());
    while(!q.empty())
    {
        //printf("t=%d\n",t);
        t+=q.top().v;
        //printf("st=%d v=%d p=%d num=%d\n",q.top().st,q.top().v,q.top().yu,q.top().num);
        if(q.top().yu==p)
        {
            if(t==k)
            {
                return 0;
            }
            else if(t<k)
            {

                return -1;
            }
            else
            {
                //printf("t=%d\n",t);
                //debug
                return 1;
            }
        }
        q.pop();
    }
}
long long s[50005];
void print(int p)
{
    Work tt;
    while(!q.empty())
    {
        q.pop();
    }
    long long t=0;
    for(int i=0; i<n; i++)
    {
        while(!q.empty()&&q.top().v<=w[i].st-t)
        {
            t+=q.top().v;
            s[q.top().num]=t;
            q.pop();
        }
        if(q.empty())
        {
            tt=w[i];
            if(tt.yu==-1)
            {
                tt.yu=p;
            }
            q.push(tt);
            t=tt.st;
        }
        else if(w[i].st-t<q.top().v)
        {
            tt=q.top();
            q.pop();
            tt.v-=w[i].st-t;
            q.push(tt);
            tt=w[i];
            if(tt.yu==-1)
            {
                tt.yu=p;
            }
            q.push(tt);
            t=tt.st;
        }
    }
    while(!q.empty())
    {
        t+=q.top().v;
        s[q.top().num]=t;
        q.pop();
    }

    for(int i=0;i<n;i++)
    {
        if(i==n-1)
        {
            printf("%I64d\n",s[i]);
        }
        else
        {
            printf("%I64d ",s[i]);
        }
    }
}
set<int>S;
int main()
{
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
    long long k;
    scanf("%d",&n);
    for(int i=0; i<n; i++)
    {
        scanf("%d%d%d",&w[i].st,&w[i].v,&w[i].yu);
        if(w[i].yu!=-1)
        {
            S.insert(w[i].yu);
        }
        w[i].num=i;
    }
    scanf("%I64d",&k);
    sort(w,w+n,cmp1);
    int left=1,right=INF,mid,ans;
    while(left<=right)
    {
        mid=(left+right)>>1;
        int f=check(mid,k);
        //printf("f=%d\n",f);
        if(f==0)
        {
            ans=mid;
            //printf("ans=%d\n",ans);
            break;
        }
        else if(f==-1)
        {
            right=mid-1;
        }
        else
        {
            left=mid+1;
        }
    }
    int L=ans;
    while(L>=1&&S.find(L)!=S.end())
    {
        L--;
    }
    int R=ans;
    while(R<=INF&&S.find(R)!=S.end())
    {
        R++;
    }
    if(L>1&&check(L,k)==0)
    {
        //debug
        printf("%d\n",L);
        print(ans);
    }
    else
    {
        //debug
        printf("%d\n",R);
        print(R);
    }

    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值