这个应用程序在Java接收到正确的输入后,输出一个数字。 input1如下所示:
3 2
1000
1010
1999
输出将是:2
对于input2:
2 1
0
输出将是: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点,我知道我应该读一本书,我在这里问这是最后的手段。我的代码出了什么问题?
答案 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;包含上面显示的迭代器。