Codeforces Round #536 (Div. 2) B. Lunar New Year and Food Ordering(思维)

 

题目链接:http://codeforces.com/contest/1106/problem/B

       题意是有n个菜,m个操作,接下来一行输入每个菜的盘数,再下来一行输入每盘菜的价格,接下来m行,每行两个数分别表示第x个菜,要买y盘,输出他要支付的价钱,如果第x个菜不够y盘,他将会去买价格最低的菜,直到买够y盘,如果所有的菜都卖完了也不够y盘,他就会不高兴,然后带着那些不够y盘的菜不给钱就走了。

       比较巧妙的思维题,写法就是按题意分类讨论然后模拟就完了,暴力的去模拟的话,亲测TLE,然后这里需要一个巧妙的转换,就是开一个id数组,将每盘菜的id按它的价格排序,然后用一个变量去记录并更新最便宜的菜的位置就好了。说的不太清楚,看呆码理解吧,不是很难。


AC代码:

#include <bits/stdc++.h>
#define maxn 100005
#define ll long long
using namespace std;
int w[maxn], cnt[maxn], id[maxn];
int n,m;

bool cmp(int x,int y){
  return w[x] < w[y];
}

int main()
{
  scanf("%d%d",&n,&m);
  for(int i=1;i<=n;i++){
    scanf("%d",&cnt[i]);
    id[i] = i;
  }
  for(int i=1;i<=n;i++) scanf("%d",&w[i]);
  sort(id + 1, id + n + 1, cmp);       // 按价格排序
  int pos = 1;         // 标记最便宜的菜的位置
  while(m--){
    int x, y;
    scanf("%d%d",&x,&y);
    int p = min(cnt[x], y);            // 取二者最小值
    ll ans = (ll)p * (ll)w[x];
    cnt[x] -= p; y -= p;
    while(y && pos <= n){              // 如果y有剩余,进入while循环
      if(cnt[id[pos]] == 0) pos++;     // 如果第pos便宜的菜卖完了 pos++
      p = min(cnt[id[pos]] , y);
      ans += (ll)p * (ll)w[id[pos]];
      cnt[id[pos]] -= p;
      y -= p;
    }
    if(y == 0) printf("%lld\n", ans);
    else puts("0");
  }
  return 0;
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值