[蓝桥杯 2019 省 A] 外卖店优先级

[蓝桥杯 2019 省 A] 外卖店优先级

题目描述

“饱了么”外卖系统中维护着 N N N 家外卖店,编号 1 1 1 N N N。每家外卖店都有一个优先级,初始时 ( 0 (0 (0 时刻)优先级都为 0 0 0

每经过 1 1 1 个时间单位,如果外卖店没有订单,则优先级会减少 1 1 1,最低减到 0 0 0;而如果外卖店有订单,则优先级不减反加,每有一单优先级加 2 2 2

如果某家外卖店某时刻优先级大于 5 5 5,则会被系统加入优先缓存中;如果优先级小于等于 3 3 3,则会被清除出优先缓存。

给定 T T T 时刻以内的 M M M 条订单信息,请你计算 T T T 时刻时有多少外卖店在优先缓存中。

输入格式

第一行包含 3 3 3 个整数 N N N M M M T T T

以下 M M M 行每行包含两个整数 t s ts ts i d id id,表示 t s ts ts 时刻编号 i d id id 的外卖店收到。

一个订单。

输出格式

输出一个整数代表答案。

样例 #1

样例输入 #1

2 6 6
1 1
5 2
3 1
6 2
2 1
6 2

样例输出 #1

1

提示

样例解释

6 6 6 时刻时, 1 1 1 号店优先级降到 3 3 3,被移除出优先缓存; 2 2 2 号店优先级升到 6 6 6

加入优先缓存。所以是有 1 1 1 家店 ( 2 (2 (2 号)在优先缓存中。

评测用例规模与约定

对于 80 % 80\% 80% 的评测用例, 1 ≤ N , M , T ≤ 10000 1 \le N,M,T \le 10000 1N,M,T10000

对于所有评测用例, 1 ≤ N , M , T ≤ 1 0 5 1 \le N,M,T \le 10^5 1N,M,T105 1 ≤ t s ≤ T 1 \le ts \le T 1tsT 1 ≤ i d ≤ N 1 \le id \le N 1idN

蓝桥杯 2019 年省赛 A 组 G 题。

暴力代码

官网最后一个测试点会爆内存

import java.util.*;
class Main
{
    public static void main(String[] args)
    {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int m = sc.nextInt();
        int t = sc.nextInt();
        int[] s = new int[n+1];     //某店的优先级
        int[][] a = new int[t+1][n+1];    //将输入转化成t时刻n店铺的订单数
        while(m-->0)
            a[sc.nextInt()][sc.nextInt()]++;
        
        List list = new ArrayList();
        for(int i=1;i<=t;i++)   //枚举时刻
        {
            for(int j=1;j<=n;j++)   //枚举店铺
            {
                if(a[i][j]!=0)  //如果有订单
                    s[j]+=a[i][j]*2;
                else
                {
                    s[j]--;
                }
                
                if(s[j]<0)
                    s[j]=0;
                    
                if(!list.contains(j) && s[j]>5)
                    list.add(j);

                if(list.contains(j) && s[j]<=3)
                    list.remove(list.indexOf(j));
            }
        }
        System.out.println(list.size());
    }
}

优化代码

import java.util.*;
class Order
{
    int ts;
    int id;
}
class Cmp implements Comparator<Order>
{
    public int compare(Order x,Order y)
    {
        if(x.ts!=y.ts)  return x.ts-y.ts;
        return x.id-y.id;
    }
}
class Main
{
    public static void main(String[] args)
    {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int m = sc.nextInt();
        int t = sc.nextInt();
        int[] score = new int[n+1];     //某店的优先级
        Order[] order = new Order[m];
        int[] last = new int[n+1];      //某店上次有订单的时刻
        for(int i=0;i<m;i++)
        {
            order[i] = new Order();
            order[i].ts=sc.nextInt();
            order[i].id=sc.nextInt();
        }
        
        Arrays.sort(order,0,m,new Cmp());
        List list = new ArrayList();
        for(int i=0;i<m;i++)   //枚举订单
        {
            int j=i;
            while(j<m && order[i].ts==order[j].ts && order[i].id==order[j].id)  //遍历所有相同的订单
                j++;
            int cnt=j-i;  //多少个相同的订单
            i=j-1;
            score[order[i].id] -= order[i].ts - last[order[i].id] - 1;
            if(score[order[i].id] < 0)
                score[order[i].id] = 0;
            if(list.contains(order[i].id) && score[order[i].id]<=3)
                list.remove(list.indexOf(order[i].id));
            
            score[order[i].id] += cnt*2;
            if(!list.contains(order[i].id) && score[order[i].id]>5)
                list.add(order[i].id);
            last[order[i].id] = order[i].ts;
        }
        
        for(int i=1;i<=n;i++)   //枚举店铺
        {
            if(last[i] < t)     //如果最后没有订单
            {
                score[i] -= t - last[i];    //不需要减一因为该店铺t时刻一定没有订单
            }
            if(list.contains(i) && score[i]<=3)
                list.remove(list.indexOf(i));
        }
        System.out.println(list.size());
    }
}
  • 12
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值