给定 3 个正整数,求最大步数将它们减少到 0
Posted
技术标签:
【中文标题】给定 3 个正整数,求最大步数将它们减少到 0【英文标题】:Given 3 positive integers, find max number of steps to reduce them to 0 【发布时间】:2020-03-26 17:54:54 【问题描述】:我正在从 CodeForces 解决this question:
我们得到三个值,
r
、g
和b
,分别代表三堆中红色、绿色和蓝色糖果的数量。 Tanya 一天不能吃两颗相同颜色的糖果,也就是说,她每天只吃两颗不同颜色的糖果。找出 Tanya 可以吃糖果的最大天数。
我做了一个简单的方法如下:
int main()
int t, r, g, b;
cin>>t;
while(t--)
int counter=0;
cin >> r >> g >> b;
while(r && g)
r--;
g--;
counter++;
while(g && b)
g--;
b--;
counter++;
while(r && b)
r--;
b--;
counter++;
cout<<counter<<"\n";
return 0;
但是,它在输入 7 4 10
和 8 2 8
上中断。我的代码分别返回7
和8
,而不是10
和9
(我不确定10
和9
如何是输入的预期答案)。 editorial 讨论对输入进行排序并检查 b <= r + g
是否返回 (r+g+b)/2
如果 true
和 r+g
否则返回。我只想说,我无法理解社论说什么。
有人可以指出为什么 我的 逻辑不正确以及我缺少什么吗?
谢谢!
【问题讨论】:
【参考方案1】:即使您的解决方案得到纠正,它也可能无法通过 codeforces 上的所有测试,因为它的时间复杂度与输入数字的值成正比。但是有一个解决方案,无论输入数字如何,运行时间都是恒定的。
首先,对3
输入的数字进行排序。如果它们没有排序,那么在每次迭代中,我们需要找到最大和最小元素,然后递减它们。如果对数字进行了排序,那么我们会立即知道最大和最小数字在哪里,因此我们可以立即将它们递减。
现在,在排序之后,让我们考虑a,b,c: a<=b<=c
的可能情况:
0.如果a
是0
(或a,b
或a,b,c
)那么这个数字显然是min(b,c)
。
1.对于a, b, c: b = c, a > 0
,最好依次递减a,b
然后a,c
,因为它会产生最大迭代次数。例如,2,3,3
-> 1,2,3
-> 0,2,2
-> 0,1,1
-> 0,0,0
。如果a = c and b = c
,那么它仍然是true
- 2,2,2
-> 1,1,2
-> 0,1,1
-> 0,0,0
。
2.对于a, b, c: a != b and b != c
,我们应该牢记1
最大化迭代次数的情况。如何到那?好吧,通过递减c
和a
,只要a
变为0
(那么就不需要大小写1
,因为我们已经可以将剩余步骤计算为min(b, c - a)
)或c
变为等于b
,然后是1
。如果我们尝试减少任何其他数字对,那么迭代次数将减少,因为b
将无缘无故减少:)。在此之后我们可以申请案例1
。
3.这种方法可以在O(1)
时间复杂度下实现。
...
int main()
int t;
std::cin >> t;
for (int i = 0; i < t; i++)
std::vector<int32_t> array(3);
for (int32_t& value : array)
std::cin >> value;
std::sort(array.begin(), array.end());
int32_t days = 0;
int32_t diff = array[2] - array[1];
days += (std::min(array[0], diff));
array[0] -= days;
array[2] -= days;
array[2] -= array[0] / 2;
days += (array[0] / 2);
array[1] -= array[0] / 2;
days += (array[0] / 2);
days += std::min(array[1], array[2]);
std::cout << days << std::endl;
return 0;
...
【讨论】:
【参考方案2】:因为你需要找到解决这个问题的最佳方法。
比如1,1,10,最优的方式是r&b,g&b。在你的方法中,结果只有 1。
因此我们需要对三个值进行排序,并始终使用最大的数字来得出答案。
【讨论】:
以上是关于给定 3 个正整数,求最大步数将它们减少到 0的主要内容,如果未能解决你的问题,请参考以下文章
正整数拆分问题 将一个给定的正整数n拆分成若干个在a到b之间的正整数之和,有多少种拆法