C ++使用ceil和length输出不正确的值

时间:2017-07-23 22:50:04

标签: java c++

这个应用程序在Java接收到正确的输入后,输出一个数字。 input1如下所示:

  • 3 2

  • 1000

  • 1010

  • 1999

输出将是:2

对于input2:

  • 2 1

  • 0

  • 1000

输出将是:1

    public class Application {

    public static void main(String[] args) {
    Scanner input = new Scanner(System.in);

    int n = input.nextInt();
    int k = input.nextInt();
    int[] c = new int[200001];
    for(int a = 0; a < n; a++){
        int b = input.nextInt();
        c[b]++;
        c[b+1000]--;
    }
    int Requests = 0;
    int maxRequests = 0;
    for(int a = 0; a < c.length; a++){
        Requests += c[a];
        if(Requests > maxRequests){
            maxRequests = Requests;

        }
    }

    System.out.println((int)(Math.ceil(((maxRequests+0.0)/k) - 0.000000001)+0.2));

}  

我用C ++制作了这个应用程序,但问题是输入1输出“1”而输入2 =“2”。这是不正确的。

我的代码如下:

int main() {

    int n;
    int k;
    cin >> n;
    cin >> k;   
    std::vector<int> c (200001);

    for(int i = 0; i < n; i++)
    {
        int b;
        cin >> b;
        c[b]++;
        c[b+1000]--;
    }

    int Requests = 0;
    int maxRequests = 0;

    for(int a = 0, length = sizeof(c); a < length; a++)
    {
        Requests += c[a];
        if(Requests > maxRequests){
            maxRequests = Requests; 
        }
    }
    int x = ceil(((((maxRequests+0.0)/k) - 0.000000001)+0.2));        
    cout << x;
    return 0;
}

过去4个小时我一直试图解决这个问题,现在凌晨4点,我知道我应该读一本书,我在这里问这是最后的手段。我的代码出了什么问题?

1 个答案:

答案 0 :(得分:2)

据我所知,两种情况下的结果都应为2。在第二种情况下,数组中的值将是1,a -1和许多0。最大值为1. 1-0.00000001 / 1 +0.2 = 1.199999999(给出或取9或2)。这显然超过1,少于2,因此ceil会将其四舍五入到2

就在C ++中实现它而言,我可能会以不同的方式完成这项工作。特别是,我利用一些标准算法来处理部分工作。你正在做的部分事情:

for(int a = 0; a<c.size(); a++)
{
    Requests += c[a];

...是std::partial_sum已经做过的事情。诀窍是partial_sum使用迭代器告诉它存放结果的位置。现在,我们可以(例如)将结果写入向量,然后扫描向量以找到最大的项目:

std::vector<int> maxes;

std::partial_sums(c.begin(), c.end(), std::back_inserter(maxes));

int maxRequests = *std::max_element(maxes.begin(), maxes.end());

至少对我来说,当我们真正只想要一个值时,写一个完整的值向量似乎是相当浪费的:到目前为止我们已经看过的最大值。一种可能性是创建一个迭代器来做到这一点(我知道这比任何人想要的都要长 - 幸运的是,它主要只是样板,所以暂时不需要太在意:

template <class T>
class keep_max_t {
    T *val;
public:
    using iterator_tag = std::output_iterator_tag;
    using value_type = void;
    using difference_type = void;
    using pointer = void;
    using reference = void;

    keep_max_t(T &t) : val(&t) {
        *val = std::numeric_limits<T>::min();
    }

    keep_max_t &operator=(T new_val) { 
        *val = std::max(*val, new_val);
        return *this; 
    }

    keep_max_t &operator++() { return *this; }
    keep_max_t &operator++(int) { return *this; }
    keep_max_t &operator*() { return *this; }
};

template <class T>
keep_max_t<T> keep_max(T &v) { return keep_max_t<T>(v); }

现在我们可以计算部分和,并更直接地保持最大值:

int maxRequests;

std::partial_sum(c.begin(), c.end(), keep_max(maxRequests));

现在让我们来看看你正在做的计算:

int x = ceil(((((maxRequests+0.0)/k) - 0.000000001)+0.2));

从中间开始:(maxRequests+0.0)基本上只是一种获取maxRequests值的奇怪方法,但是从int转换为double。我们想要一个double(或至少一些浮点类型),因为下一步是将结果除以k

我们做的更简单一点:make k a double,当我们maxRequests / k时,编译器会自动将maxRequests转换为{{1}并且在双精度浮点数学中进行除法。因此,我们可以简化为:

double,

从那里开始,事情变得非常奇怪 - 由于我仍然无法理解的原因,我们减去一个数字,然后添加另一个数字。我们可以提前将它们加在一起,以获得:

double k;
cin >> k;

// ...

int x = ceil((maxRequests/k) // ...;

最后,我们都知道乘法和除法的优先级高于加法和减法,因此我们可以删除无关的括号,因此变为:

std::ceil((maxRequests / k) + 0.199999999);

我仍然不确定魔法std::ceil(maxRequests / k + 0.199999999); 的含义,但除了这个神奇的数字之外,它现在还相当可读。

当然,我们也无疑希望在函数中进行计算,而不是将所有内容都推送到0.199999999

为了便于测试,我们可以将测试输入值放入main,并将它们提供给我们的函数(并打印出结果)。把所有这些放在一起,我们可能会得到类似这样的代码:

main

...其中&#34; keeper.h&#34;包含上面显示的迭代器。