在这个特定的任务中,尽量把大的数字四舍五入

本文关键字:四舍五入 数字 任务 | 更新日期: 2023-09-27 17:51:15

我正在尝试解决一个难题:http://www.codeabbey.com/index/task_view/two-printers

问题是我在四舍五入时遇到了问题,我不确定问题在哪里,也不知道在执行操作之前应该四舍五入多少。下面是前4个测试用例的输入(第一个数字是第一台打印机打印页面的秒数,第二个数字是第二台打印机打印页面的秒数,以及要打印的页面数):

15 15 46491255

5900 13309 60565

13 3 75408735

80025 84130 10370

以下是我的答案:348684413/247579340/183808792/425305709

正确答案如下:348684420/247581700/183808794/425332875

下面是我的代码:
using System;
public class Test
{
    public static void Main()
    {
        int n = int.Parse(Console.ReadLine());
        string[] container = new string[3];
        double[] results = new double[n];
        double printer1, printer2, pages;
        double x, y;
        for (int i = 0; i < n; i++)
        {
            x = 0;
            y = 0;
            container = Console.ReadLine().Split(' ');
            printer1 = double.Parse(container[0]);
            printer2 = double.Parse(container[1]);
            pages = double.Parse(container[2]);
            x = (1 / printer1) + (1 / printer2);
            y = Math.Round((pages / x), MidpointRounding.AwayFromZero);

            results[i] = y;
        }
        for (int i = 0; i < n; i++)
        {
            Console.Write(results[i] + " ");
        }
    }
}

在这个特定的任务中,尽量把大的数字四舍五入

代码有两个问题:

一个小问题是,您总是希望四舍五入到下一个整数,但这不是MidpointRounding所做的。您想使用Ceiling

但是主要的问题是代码没有考虑到打印机只能打印整页。想象一个极端的例子:12 40 6: <>之前|时间|打印机1 |打印机2 |总数|| (sec)| (pages) | (pages) | (pages) | (pages) |+------------------------------+---------|| 12 | 1 | 0.3 | 1.3 || 24 | 2 | 0.6 | 2.6 || 36 | 3 | 0.9 | 3.9 || 40 | 3.333 | 1.0 | 4.333 || 48* | 4 | 1.2 | 5.2 || 60 | 4 | 1.667 | 5.667 || 80 | 4 | 2 | 6 |之前

请注意48秒时发生的事情:第一台打印机已经打印了4页,而另一台仍在打印第二页。理想情况下,根据代码,第一台打印机可以通过"帮助"较慢的打印机完成第二页的剩余部分来加快速度,在6/(1/12 + 1/40)=不到56秒的时间内完成。但实际上,打印机不能共享页面;每个打印机必须只打印完整的页面,所以我们别无选择,只能让第一台打印机空闲22秒,而另一台打印机完成它的页面。

但是我们可以做得更好,如果我们预测到这一点,只给较慢的打印机一个页面:

<>之前|时间|打印机1 |打印机2 |总数|| (sec)| (pages) | (pages) | (pages) | (pages) |+------------------------------+---------|| 12 | 1 | 0.3 | 1.3 || 24 | 2 | 0.6 | 2.6 || 36 | 3 | 0.9 | 3.9 || 40* | 3.333 | 1 | 4.333 || 48 | 4 | 1 | 5 || 60 | 5 | 1 | 6 |之前

在这里,我们在打印一页后让较慢的打印机闲置,意识到如果我们让较快的打印机多打印一页,我们将在60秒内完成。因此,根据相对速度和页数,并认识到打印机只能以完整的页数为单位共享工作,在完成时,将较慢的另一页交给可能是更明智的,因为快的那个最终会"赶上"。

解决这个问题的方法是计算出给每个打印机多少页。把这些页面想象成一张连续的长纸。每台打印机从一端开始打印,在打印过程中向中间"赛跑"。当它们相遇时,快的那个会打印5次;40/(12 + 40) = 3.8页。但实际上,它只能处理完整的页面,所以我们需要看看哪个更好:让它打印额外的0.2页,或者在3页后停止它,让速度较慢的打印0.8页。在这种情况下,很明显我们应该把0.2页给更快的打印机,但我们可以通过注意0.2(12)<0.8(40)。

我假定您不是在寻找指定问题的完整代码答案,因为您所指向的站点通常是为想要学习如何解决这类问题的人准备的。

你的问题不在你的答案的四舍五入。相反,它在你的算法中。

如果你把你的算法和网站上给出的例子对比一下,你会发现你的算法不起作用。

对于"3 5 4"的第二个例子,程序给出7.5(舍入之前)。不管你怎么取7.5,你都不会得到正确的答案9。

根据输入数据,printer1或printer2将最终成为长杆,并且该打印机将以整数页数结束(打印机不能共享要打印的页面)—这里根本没有涉及四舍五入。

谢谢大家。事实是,即使我解决了任务,我也不觉得这完全是我的成就....即使你的解释写得很好,我也很难理解。经过一天的破解,这是我最终得到的结果。我只复制其中的Algo部分:

 double printedPages1 = Math.Ceiling((printer2 * pages) / (printer1 + printer2));
  double printedPages2 = Math.Ceiling((printer1 * pages) / (printer1 + printer2));
        if (printedPages1 * printer1 < printedPages2 * printer2)
        {
            time = Math.Ceiling(printedPages1 * printer1);
        }
        else
        {
            time = Math.Ceiling(printedPages2 * printer2);
        }

        results[i] = time; // I add the result(time) in an array

嗯,也许不是最好的方法……如果你有任何建议,请发帖:)