Codeforces Round #536 (Div. 2) B. Lunar New Year and Food Ordering 简单模拟题

4 篇文章 0 订阅

B. Lunar New Year and Food Ordering

题意:

第一行输入n,m。餐馆一共有n种菜,会有m个顾客前来点菜。

第二行是每种菜的数量,第三行是每种菜(一道菜)的成本。

从第四行开始有m行,每一行输入两个数(x   y) 分别表示第几道菜 和 需要几道这样的菜。如果顾客所点的这道菜没有那么多,就从所有菜中价格最便宜的补(补的菜的价格是菜原来的价格),如果有多种价格相同最便宜的菜,就先从先出现的菜拿。 一个顾客如果不能够拿到y道菜,他就会生气的离开,它的成本就为0。

输出每一位顾客所需的成本。

一直没想清楚怎样将排好序的菜的位置 与 输入的原菜的位置相联系,看了大佬的代码发现只需要一个存储位置的数组就可以。。。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e5+10;
ll num[maxn],v[maxn];
int indx[maxn];
int cmp(int x,int y)
{
    if(v[x]==v[y])
        return x<y;
    return v[x]<v[y];
}
int main()
{
    int n,m;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
        scanf("%I64d",num+i);
    for(int i=1;i<=n;i++)
        scanf("%I64d",v+i);
    for(int i=1;i<=n;i++)
        indx[i] = i;
    sort(indx+1,indx+n+1,cmp);
    int x,y;
    int k = 1;
    while(m--)
    {
        scanf("%d%d",&x,&y);
        if(num[x]>=y)        //第一种情况
        {
            num[x] -= y;
            printf("%I64d\n",v[x]*y);
        }
        else         //第二种情况
        {
            ll sum = num[x]*v[x];
            y -= num[x];
            num[x] = 0;
            int flag = 0;  //判断顾客是否会生气离开
            for(;k<=n;k++)  //每次从1开始遍历会超时
            {

                if(num[indx[k]]<y)
                {
                    sum += num[indx[k]]*v[indx[k]];
                    y -= num[indx[k]];
                    num[indx[k]] = 0;
                }
                else
                {
                    sum += v[indx[k]]*y;
                    num[indx[k]] -= y;
                    break;         // 直接跳出循环且所对应的数量已经减少,当为后来的顾客补菜时还是从 indx[k] 开始
                }
                if(k==n)     // 如果顾客已经得到y道菜就会在上一步跳出循环,所以当条件成立时,就表示顾客生气离开
                    flag = 1;
            }
            if(flag)
                printf("0\n");
            else
                printf("%I64d\n",sum);
        }
    }
    return 0;
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值