这是我到目前为止所遇到的问题和代码。
我有一系列正数。序列的长度大于8,负数(不是序列的一部分)是序列末端的符号。我需要编写一个程序(通过时间和内存使用有效),找到由8个或更多位置分隔的2个元素的最大乘积。保证答案小于2000000000。
例如,对于{1 2 3 4 5 6 7 8 9 10 -1}
,答案为20
。
我的代码:
#include <stdio.h>
#include <stdlib.h>
static long long int find_max(long int *v1, long int size) {
const int d = 8;
long int arr[8];
long int maxi = 0;
long long int max_pr = 0;
for (int i = 1; i < d + 1; i++) {
arr[i % d] = v1[i - 1];
}
for (int j = d + 1; j < size + 1; j++) {
if (arr[j % d] > maxi)
maxi = arr[j % d];
if (v1[j - 1] * maxi > max_pr)
max_pr = v1[j - 1] * maxi;
arr[j % d] = v1[j - 1];
}
return max_pr;
}
int main() {
long int seq[100000];
long int n = 0;
while (n < 100000 && scanf("%ld", &seq[n]) == 1) {
if (seq[n] < 0) {
break; //vector.push_back was too slow
}
n++;
}
long long int answer = find_max(seq, n);
printf("%lld ", answer);
return 0;
}
这是关于算法和数据结构的开放课程的作业问题,与我的学位无关。我的代码在测试系统上失败了。我已经尝试解决这个问题几天了,并且无法理解我在这里做错了什么,因为它对我能提出的每个例子都很好。
我真的很感激任何帮助。
答案 0 :(得分:3)
这很容易在线性时间内完成,无需任何额外的存储空间。想想哪些数字可能是可能的解决方案:它可能是第九个数字的第一个数字。它可能是前两个中最大的,也就是第十个中的最大值。它可能是前三个中最大的,第十一个,依此类推。所以:
Set maxN = 0, maxProduct = 0, i = 0.
As long as v1 [i + 8] ≥ 0:
If v1 [i] > maxN then maxN = v1 [i]
If v1 [i + 8] * maxN > maxProduct then maxProduct = v1 [i + 8] * maxN.
Let i = i + 1.
就是这样。
答案 1 :(得分:1)
您的算法没有按照问题要求您执行此操作。特别是,arr[8]
和i%d
不是必需的。
以下是如何在O(n)时间内解决此问题的方法,该方法效率最高:
maxSoFar
seq
。将maxSoFar[i]
设置为seq
i
的最高值
seq
开始再次遍历数组8
,找到max
的{{1}}。以下是随机序列seq[i] * maxSoFar[i-8]
的示例:
maxSoFar
第二遍应该产生以下值:
seq: 1 4 3 5 2 12 8 6 14 19 7 9 25 20 13
maxSoFar: 1 4 4 5 5 12 12 12 14 19 19 19 25 25 25
因此,结果是240。
注意:可以删除数组maxSoFar。你能看到怎么样?