试图在这个特定任务上围绕大数字

时间:2014-03-22 11:08:34

标签: c# rounding

我试图解决一个难题: 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] + " ");
        }

    }
}

3 个答案:

答案 0 :(得分:2)

代码存在两个问题:

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

但主要问题是代码没有考虑到打印机只能打印整页。想象一下12 40 6的一个极端例子:

| Time | Printer 1 | Printer 2 | Total   |
| (sec)| (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秒,而另一台打印机完成其页面。

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

| Time | Printer 1 | Printer 2 | Total   |
| (sec)| (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)<1来解决一般情况。 0.8(40)。

答案 1 :(得分:1)

我将假设您没有找到指定问题的完整代码答案,因为您指向的网站通常适用于想要学习如何解决这些问题的人。

您的问题不在于您的答案。相反,它在你的算法中。

如果您根据网站上提供的示例检查算法,则会发现您的算法不起作用。

对于&#34; 3 5 4&#34;的第二个例子,你的程序给出7.5(舍入前)。无论你以哪种方式绕7.5,你都不会得到9的正确答案。

打印机1或打印机2将最终成为长杆,具体取决于输入数据,并且打印机最终会有一个整数页(打印机无法共享页面进行打印) - 没有四舍五入到这里。

答案 2 :(得分:0)

非常感谢你们。事实是,即使我解决了这个任务,我也不觉得这完全是我的成就......甚至太难以理解你的解释,即便如此,他们的写得非常好。 经过一天的解决,这就是我最后得到的结果。我只会复制它的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

好吧也许不是最好的方式...如果您有任何建议请发布:)