买糖果

买糖果

n 个糖果店,围成一圈。

店铺按顺时针顺序从 1n 编号,n 号店铺与 1 号店铺相邻。

i 号店铺的单个糖果售价为 ai 元。

李华拿着 T 元钱去购买糖果,具体购买过程如下:

  1. 初始时,他位于 1 号店铺。
  2. 如果他现有的钱足够在当前店铺购买一个糖果,他就会立即购买一个糖果,否则他将不会在当前店铺购买糖果。随后,不论他是否在当前店铺购买糖果,他都会按顺时针顺序前往下一个店铺。
  3. 他将不断重复过程 2,直到剩余的钱在所有店铺都买不起糖果为止。

请问,最终李华一共购买到多少个糖果。

输入格式

第一行包含两个整数 n,T

第二行包含 n 个整数 a1,a2,,an

输出格式

一个整数,表示一共购买到的糖果数量。

数据范围

6 个测试点满足 1n10
所有测试点满足 1n2×1051T10181ai109

输入样例1:

3 38
5 2 5

输出样例1:

10

输入样例2:

5 21
2 4 100 2 6

输出样例2:

6

 

解题思路

  先暴力枚举算一下走一圈可以买多少糖果,如果某个糖果买不了,当前这圈买不了那么后面每一圈肯定都买不了,因此可以跳过。假设在这一圈里可以买的糖果数量是cnt,花费是sum,那么只要总钱数Tsum,那么就可以转一圈买cnt个糖果,直到总钱数小于sum为止。在总钱数小于sum之前每一圈都是一样的,总钱数都是减去sum,糖果数量加上cnt。一共可以转Tsum圈,那么一共可以买的糖果数量就是Tsum×cnt,剩余的钱就是T%sum

  每次计算完后都至少有一个糖果店被减去,一共有n个糖果店,那么最坏情况下时间复杂度为O(n2)。但事实上时间复杂度为O(nlogT)。因为每次sum都小于等于T,即T每次取模的数都小于等于T,这里就会有个性质,即T%sum<T2,也就是每转一次T至少除以2

  证明如下。如果sum>T2,那么T%sum=Tsum<T2,因为此时T除以sum的商为1。而如果sumT2,那么T%sum<T2

  AC代码如下:

复制代码
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 typedef long long LL;
 5 
 6 const int N = 2e5 + 10;
 7 
 8 int a[N];
 9 
10 int main() {
11     int n;
12     LL m;
13     scanf("%d %lld", &n, &m);
14     for (int i = 0; i < n; i++) {
15         scanf("%d", a + i);
16     }
17     
18     LL ret = 0;
19     while (true) {
20         LL cnt = 0, sum = 0;
21         for (int i = 0; i < n; i++) {
22             if (sum + a[i] <= m) {
23                 cnt++;
24                 sum += a[i];
25             }
26         }
27         
28         if (cnt == 0) break;
29         ret += m / sum * cnt;
30         m %= sum;
31     }
32     
33     printf("%lld", ret);
34     
35     return 0;
36 }
复制代码

 

参考资料

  AcWing 4623. 买糖果(AcWing杯 - 周赛):https://www.acwing.com/video/4445/

posted @   onlyblues  阅读(39)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效
Web Analytics
点击右上角即可分享
微信分享提示