zoukankan      html  css  js  c++  java
  • P2107 小Z的AK计划


    题目描述

    在小Z的家乡,有机房一条街,街上有很多机房。每个机房里都有一万个人在切题。小Z刚刷完CodeChef,准备出来逛逛。

    机房一条街有 n 个机房,第 i 个机房的坐标为 xi ,小Z的家坐标为 0。小Z在街上移动的速度为1,即从 x1 到 x2 所耗费的时间为 |x1 − x2|。 每个机房的学生数量不同,ACM 题目水平也良莠不齐。小Z到达第 i 个机房后,可以花 ti 的时间想题,然后瞬间 AK;当然,也可以过机房而不入。

    小Z现在只有 m 个单位时间,之后他就该赶着去打 Codeforces 了。现在他想知道自己最多能在多少个机房 AK,希望你帮帮他。

    知识点
    二叉堆
    优先队列

    输入格式:
    第一行包含两个整数 n,m。

    接下来 n 行,每行包含两个整数 xi,ti 。

    输出格式:
    第一行包含一个整数,表示小Z最多能 AK 的机房数量。

    输入输出样例

    输入样例#1:
    2 10
    1 100
    5 5
    输出样例#1:
    1
    说明

    【数据规模】

    对于 30% 的数据,n ≤ 20。

    对于 60% 的数据,n ≤ 1000。

    对于 100% 的数据,1 ≤ n ≤ 10^5,0 ≤ m,xi ≤ 10^18,0 ≤ ti ≤ 10^9。
    这道题因为路径长度不定,若同时考虑路径长和思考时间两个因素会很麻烦,但是因为一条路绝对不会重复走(原因当然是浪费时间,还没有意义),所以我们可以考虑通过枚举使路径长这一因素变为一个固定值,这样我们只需要通过贪心来从小到大取思考时间即可,但这道题数据量比较大,则不能用插入排序(因为一定会超时),所以我们换一种考虑方式,使每次新进来的值加上我原来在上一个点所用的可以得到最多的AK机房数的几种情况中思考时间最少的时间加上路径所用时间,判断是否超时,同时,将此机房思考时间入队;若不超,则可将此机房添加到答案中去;若超时,则将所取的时间的队列中的最大值弹出,同时时间减去最大值
    #include<bits/stdc++.h>
    using namespace std;
    const int ma=1e5+10;
    struct zx{long long x;int y;};
    zx s[ma];
    long long a[ma],m;
    int n,cnt,ans;
    void su(int x)
    {
    while(x>>1>=1&&a[x>>1]<a[x])
    {
    swap(a[x>>1],a[x]);
    x>>=1;
    }
    }
    void sx(int x)
    {
    while(x<<1<=cnt)
    {
    int t=x,p=x<<1;
    if(a[p]>a[t])
    t=p;
    if(p+1<=cnt&&a[p+1]>a[t])
    t=p+1;
    if(t==x)
    break;
    swap(a[t],a[x]);
    x=t;
    }
    }
    void add(int x)
    {
    a[++cnt]=x;
    su(cnt);
    }
    void rm()
    {
    a[1]=a[cnt--];
    sx(1);
    }
    bool cmp(zx c,zx d)
    {
    return c.x<d.x;
    }
    int main()
    {
    long long p=0,x;
    int y,cn=0;
    scanf("%d%lld",&n,&m);
    for(int i=1;i<=n;i++)
    {
    scanf("%lld%d",&x,&y);
    if(x<=m)//如果路程时间已经超过可用时间,那么到此机房为止所能AK的机房数一定为零,也就没有做的必要
    {
    s[++cn].x=x;
    s[cn].y=y;
    }
    }
    sort(s+1,s+1+cn,cmp);//按照路程排序
    for(int i=1;i<=cn;i++)
    {
    p+=s[i].x+s[i].y-s[i-1].x;//加上这个机房的路径和思考时间,同时减去上一个机房的路径时间
    add(s[i].y);//入队* (1)
    ans++;
    if(p>m)
    {
    ans--;
    p-=a[1];//减去最大值*(2)
    rm();//弹出* (3)
    }
    }
    printf("%d",ans);
    return 0;
    }
    带*号的步骤可用优先队列实现(这样就不用打上面的函数啦)
    priority_queue<int,vector<int>,less<int> >q;
    (1):q.push(s[i].y);
    (2):p-=q.top();
    (3):q.pop();

  • 相关阅读:
    Maidsafe-去中心化互联网白皮书
    The Top 20 Cybersecurity Startups To Watch In 2021 Based On Crunchbase
    Top 10 Blockchain Security and Smart Contract Audit Companies
    The 20 Best Cybersecurity Startups To Watch In 2020
    Blockchain In Cybersecurity: 11 Startups To Watch In 2019
    004-STM32+BC26丨260Y基本控制篇(阿里云物联网平台)-在阿里云物联网平台上一型一密动态注册设备(Android)
    涂鸦开发-单片机+涂鸦模组开发+OTA
    000-ESP32学习开发-ESP32烧录板使用说明
    03-STM32+Air724UG远程升级篇OTA(阿里云物联网平台)-STM32+Air724UG使用阿里云物联网平台OTA远程更新STM32程序
    03-STM32+Air724UG远程升级篇OTA(自建物联网平台)-STM32+Air724UG实现利用http/https远程更新STM32程序(TCP指令,单片机程序检查更新)
  • 原文地址:https://www.cnblogs.com/LWL--Figthing/p/9108933.html
Copyright © 2011-2022 走看看