感谢大佬们的点赞Orz\color{purple}{感谢大佬们的点赞~Orz}感谢大佬们的点赞 Orz

题目描述

农业,尤其是生产牛奶,是一个竞争激烈的行业。

Farmer John 发现如果他不在牛奶生产工艺上有所创新,他的乳制品生意可能就会受到重创!

幸运的是,Farmer John 想出了一个好主意。

他的三头获奖的乳牛,Bessie、Elsie 和 Mildred,各自产奶的口味有些许不同,他打算混合这三种牛奶调制出完美的口味。

为了混合这三种不同的牛奶,他拿来三个桶,其中分别装有三头奶牛所产的奶。

这些桶可能有不同的容积,也可能并没有完全装满。

然后他将桶 111 的牛奶倒入桶 222,然后将桶 222 中的牛奶倒入桶 333,然后将桶 333 中的牛奶倒入桶 111,然后再将桶 111 的牛奶倒入桶 222,如此周期性地操作,共计进行 100100100 次(所以第 100100100 次操作会是桶 $1 $倒入桶 222)。

当 Farmer John 将桶 aaa 中的牛奶倒入桶 bbb 时,他会倒出尽可能多的牛奶,直到桶 aaa 被倒空或是桶 bbb 被倒满。

请告诉 Farmer John 当他倒了 100100100 次之后每个桶里将会有多少牛奶。

输入格式

输入文件的第一行包含两个空格分隔的整数:第一个桶的容积 c1c_1c1​,以及第一个桶里的牛奶量 m1m_1m1​。

第二和第三行类似地包含第二和第三个桶的容积和牛奶量。

输出格式

输出三行,给出倒了 100100100 次之后每个桶里的牛奶量。

数据范围

1≤c1,m1≤109\color{Red}{1≤c_1,m_1≤10^9}1≤c1​,m1​≤109

输入样例

10 3
11 4
12 5

输出样例

0
10
2

样例解释

在这个例子中,每倒一次之后每个桶里的牛奶量如下:

初始状态:   3  4  5
1. 桶1->2:  0  7  5
2. 桶2->3:  0  0  12
3. 桶3->1:  10 0  2
4. 桶1->2:  0  10 2
5. 桶2->3:  0  0  12
(之后最后三个状态循环出现……)

算法1

(朴素版暴力迭代模拟) O(1)\color{Red}{O(1)}O(1)
  • 读入3个桶的容积和牛奶量

  • 从第一个桶开始idx = 1,则下一个桶next = (idx + 1) % 4 ? idx + 1 : 1

  • 设下一个桶为nextnextnext,则nextnextnext桶的容积为next(v)next(v)next(v),nextnextnext桶的牛奶量为next(w)next(w)next(w),则有

时间复杂度:O(1)O(1)O(1)

C++ 代码

#include <iostream>
#include <cstring>
#include <algorithm>using namespace std;typedef pair<int, int> PII;//容积,牛奶量PII a[4];int main()
{for (int i = 1; i <= 3 ; i++ )//读入3个桶的容积和牛奶量{int x, b;scanf("%d%d", &x, &b);a[i] = {x, b};}int idx = 1;//记录一下从第一个桶开始for (int i = 0; i < 100; i ++ )//迭代100次{int next = (idx + 1) % 4 ? idx + 1 : 1;//应该往哪个桶倒idx->nextint v = a[next].first;//查看一下next桶的容积int w = a[next].second;//查看一下next桶的牛奶量if (v == w)//如果next桶的容积等于牛奶量了,说明不需要再倒牛奶了~{}else if (a[idx].second + w <= v)//如果idx桶的牛奶量与next桶的牛奶量要小于next桶的容积{a[next].second = a[idx].second + w;//更新next桶的牛奶量a[idx].second = 0;//idx桶的牛奶量为0}else //如果idx桶的牛奶量与next桶的牛奶量要大于next桶的容积{a[idx].second -= v - w;//更新idx桶的剩余的牛奶量a[next].second = v;//next桶的牛奶量则为其容积}idx = next;//idx桶指向下一个桶(next)}for (int i = 1; i <= 3; i ++ )//输出迭代100次的答案~printf("%d\n", a[i].second);return 0;
}

算法2

(找环进行优化操作)

由我们的样例解释可知

初始状态:   3  4  5
1. 桶1->2:  0  7  5
2. 桶2->3:  0  0  12
3. 桶3->1:  10 0  2
4. 桶1->2:  0  10 2
5. 桶2->3:  0  0  12
(之后最后三个状态循环出现……)

可以找到一个环\color{Red}{环}环,使得只用计算后续经过多少个环\color{Red}{经过多少个环}经过多少个环后再经过多少步得到的最终状态\color{Red}{再经过多少步得到的最终状态}再经过多少步得到的最终状态~
如下图所示:

我们只需要用一个字符串记录三个桶牛奶量的状态,利用map看之前是否出现过,出现过的话,我们就找到了一个环直接退出循环,计算经过``p``圈后还需走多少步达到100次,最终输出答案即可
这样我们就不用枚举100次了~

C++ 代码

#include <iostream>
#include <cstring>
#include <algorithm>
#include <unordered_map>using namespace std;typedef pair<int, int> PII;//容积,牛奶量PII a[4];
unordered_map<string, int> state;
int r;
string s;int main()
{for (int i = 1; i <= 3 ; i++ ){int x, b;scanf("%d%d", &x, &b);a[i] = {x, b};}int idx = 1;for (int i = 1; i <= 100; i ++ ){int next = (idx + 1) % 4 ? idx + 1 : 1;int v = a[next].first;int w = a[next].second;if (v == w){}else if (a[idx].second + w <= v){a[next].second = a[idx].second + w;a[idx].second = 0;}else {a[idx].second -= v - w;a[next].second = v;}idx = next;/*上方的注释请看朴素版的算法~*///合成一下状态(桶1的牛奶量, 桶2的牛奶量, 桶3的牛奶量)s = to_string(a[1].second) + " " +  to_string(a[2].second) + " " + to_string(a[3].second);if (!state.count(s))//如果该状态在之前没有,则插入该状态state[s] = i;else //若有,则找到环的大小,并退出循环{r = (100 - i) % (i - state[s]);break;}}int x = state[s] + r ? state[s] + r : 1;//找到最终状态的位置~for (auto t : state)//找到最终状态`if (t.second == x){s = t.first;break;}//处理一下输出结果~   int t = s.find(' ');for (int i = 0; i < t; i ++ ) printf("%c", s[i]);s[t] = '.';puts("");int p = s.find(' ');for (int i = t + 1; i <= p; i ++ ) printf("%c", s[i]);s[p] = '.';puts("");int len = s.length();for (int i = p + 1; i < len; i ++ ) printf("%c", s[i]);puts("");return 0;
}

Acwing春季每日一题 混合牛奶(朴素做法和优化做法)相关推荐

  1. 4.3每日一题|混合牛奶(c++)

    今日题目 [USACO1.3]混合牛奶 Mixing Milk - 洛谷

  2. AcWing春季每日一题 Week1

    文章目录 1.AcWing 3346. 你知道你的ABC吗 2.AcWing 3358. 放养但没有完全放养 3.AcWing 3370. 牛年 4.AcWing 3745. 牛的学术圈 I 5.Ac ...

  3. AcWing寒假每日一题2058. 笨拙的手指

    AcWing寒假每日一题2058. 笨拙的手指 题目描述 奶牛贝茜正在学习如何在不同进制之间转换数字. 但是她总是犯错误,因为她无法轻易的用两个前蹄握住笔. 每当贝茜将数字转换为一个新的进制并写下结果 ...

  4. AcWing寒假每日一题

    **此文章持续更新,直至寒假没有每日一题!!!! 习题目录 Week 1: 货仓选址 数字三角形 Week 2 蛇形矩阵 红与黑 回文平方 剪绳子 分巧克力 校门外的树(简单暴力法) 奖学金 十三号星 ...

  5. 春季每日一题2022 Week 2 【完结】

    目录 1671. 三角形[暴力] 1659. 社交距离 I[二分] 1714. 混合牛奶[模拟] 1695. 果壳游戏[枚举] 1671. 三角形[暴力] #include<bits/stdc+ ...

  6. 混合牛奶(春季每日一题 9)

    农业,尤其是生产牛奶,是一个竞争激烈的行业. Farmer John 发现如果他不在牛奶生产工艺上有所创新,他的乳制品生意可能就会受到重创! 幸运的是,Farmer John 想出了一个好主意. 他的 ...

  7. AcWing 1695 果壳游戏 题解(春季每日一题)

    有一些思维的简单模拟 原题 #include<bits/stdc++.h>using namespace std;const int N = 110;int n; int ans;//记录 ...

  8. AcWing 1671 三角形 题解(春季每日一题)

    注意一下范围,模拟即可 原题 #include<bits/stdc++.h>using namespace std;#define int long long #define pb pus ...

  9. AcWing 1671. 三角形 (春季每日一题 暴力模拟)

    Farmer John 想要给他的奶牛们建造一个三角形牧场. 有 NN 个栅栏柱子分别位于农场的二维平面上不同的点 (X1,Y1)-(XN,YN)(X1,Y1)-(XN,YN). 他可以选择其中三个点 ...

最新文章

  1. 数字光端机和模拟视频光端机的六个不同点
  2. Vscode Todo Tree插件
  3. Java高并发编程详解系列-线程池原理自定义线程池
  4. android Binder机制(一)架构设计
  5. thinkphp5部署于Linux中nginx多站点解决方案
  6. 显示菜单栏_mac菜单栏不显示了,如何设置?
  7. C#.Net 扩展方法
  8. 网络工程制图论文计算机,计算机工程制图设计分析论文
  9. STM32F103ZET6+IIC+SHT20温湿度传感
  10. TKinter美化库——tkkbootstrap
  11. 【dxf图形识别】使用C#将线段、圆弧、圆等特征写入dxf文件
  12. visual studio C++冒号:与双冒号::的使用说明
  13. 验证“哥德巴赫猜想 - C/C++ 分支与循环
  14. 基于thinkphp5.0和支付宝面对面扫码支付DEMO制作的扫码支付
  15. 【图解】连狗子都能看懂的Python基础总结(二)什么是库、包、模块?
  16. iOS_导航栏的navigationBar.hidden与navigationBarHidden的区别
  17. Word里MathType无法使用为灰色
  18. 狸窝全能转换器安卓版_第三十二讲 如何运用“狸窝”剪辑视频
  19. 自学SQL网题解(0-5课题解)
  20. 如何将Firebase Analytics添加到NativeScript移动应用程序中

热门文章

  1. Windows 7 SP1不能更新的问题
  2. SAMSUNG i535(Verizon版S3)不能使用电信3G网络的问题
  3. isbn书号查询php代码,php根据isbn书号查询amazon网站上的图书信息的示例_PHP教程
  4. mac下如何将adobe acrobat reader dc设为.pdf的默认打开方式?
  5. 多传感器融合track fusion
  6. hdu-7113 Matrix 组合数学(计算贡献
  7. oppo手机计算机的隐藏功能介绍,OPPO手机6大隐藏功能,你知道吗
  8. Vue视频切换src,画面不变化的问题
  9. 计算机批量制作邀请函步骤,如何利用Word批量制作邀请函
  10. html5图片按钮播放,html 播放 按钮