C++ 数组中由8个或更多位置分隔的两个元素的最大乘积

C++ 数组中由8个或更多位置分隔的两个元素的最大乘积,c++,c,algorithm,time-complexity,C++,C,Algorithm,Time Complexity,这是我到目前为止遇到的问题和代码 我有一个正数序列。序列的长度大于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

这是我到目前为止遇到的问题和代码

我有一个正数序列。序列的长度大于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;
}
#包括
#包括
静态长整型查找_max(长整型*v1,长整型大小){
常数int d=8;
长整数arr[8];
长整数最大值=0;
long long int max_pr=0;
对于(int i=1;imaxi)
maxi=arr[j%d];
如果(v1[j-1]*最大值>最大值)
max_pr=v1[j-1]*maxi;
arr[j%d]=v1[j-1];
}
返回最大值;
}
int main(){
长整数序列[100000];
长整数n=0;
而(n<100000&&scanf(“%ld”,&seq[n])==1){
if(seq[n]<0){
break;//vector.push_back太慢了
}
n++;
}
long-long-int-answer=find_max(seq,n);
printf(“%lld”,答案);
返回0;
}
这是一个关于算法和数据结构的开放课程的家庭作业问题,与我的学位无关。我的代码在测试系统上失败。我已经试着解决这个问题好几天了,但我不明白我在这里做错了什么,因为它对我能想到的每个例子都很有效


我非常感谢您的帮助。

您的算法没有按照问题要求执行。特别是,
arr[8]
i%d
是不必要的

以下是如何在O(n)时间内解决此问题,这是最有效的方法:

  • 制作一个大小等于数组大小的数组
    maxSoFar
  • 从左向右移动阵列
    seq
    。将
    maxSoFar[i]
    设置为
    i
    左侧的
    seq
    的最大值
  • 从索引
    8
    开始再次遍历数组
    seq
    ,并找到
    seq[i]*maxSoFar[i-8]
    max
以下是随机序列的
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
第二遍应产生以下值:

seq:             1 4 3 5 2 12  8  6 14 19  7  9  25  20  13
maxSoFar[i-8]:   - - - - -  -  -  -  1  4  4  5   5  12  12
mul:             - - - - -  -  -  - 14 76 28 45 125 240 156
因此,结果是240


注意:可以消除阵列maxSoFar。你知道怎么做吗?

你的算法没有按照问题的要求去做。特别是,
arr[8]
i%d
是不必要的

以下是如何在O(n)时间内解决此问题,这是最有效的方法:

  • 制作一个大小等于数组大小的数组
    maxSoFar
  • 从左向右移动阵列
    seq
    。将
    maxSoFar[i]
    设置为
    i
    左侧的
    seq
    的最大值
  • 从索引
    8
    开始再次遍历数组
    seq
    ,并找到
    seq[i]*maxSoFar[i-8]
    max
以下是随机序列的
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
第二遍应产生以下值:

seq:             1 4 3 5 2 12  8  6 14 19  7  9  25  20  13
maxSoFar[i-8]:   - - - - -  -  -  -  1  4  4  5   5  12  12
mul:             - - - - -  -  -  - 14 76 28 45 125 240 156
因此,结果是240


注意:可以消除阵列maxSoFar。你知道怎么做吗?

这很容易在线性时间内完成,而不需要任何额外的存储。想想哪些数字可能是可能的解决方案:可能是第一个数字乘以第九个数字。它可能是前两个中最大的,是第十个的倍。它可能是前三个中最大的一个,乘以第十一个,依此类推。因此:

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.

就这样

这在线性时间内非常容易完成,无需任何额外存储。想想哪些数字可能是可能的解决方案:可能是第一个数字乘以第九个数字。它可能是前两个中最大的,是第十个的倍。它可能是前三个中最大的一个,乘以第十一个,依此类推。因此:

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.

就这样

今后请坚持理智的支撑方式。你的代码以前是无法读取的。另外,我们能得到提示吗?你能提供一个失败的测试用例吗?您的代码到底出了什么问题?@reousasteron这是任务描述的一部分。只是用作序列结束的标志,因为它的长度未知。是的,如果你把它拆下来就完全可以了it@Barry不幸的是,我不知道哪里出了问题,也没有任何测试用例的例子。我把它发送到我的课程的在线测试系统,它只说它在测试8中失败,并且给出了一个错误的答案。你假设序列的长度最多为100000。为什么?正如gnasher729的回答所示,您不需要分配一个数组来存储整个序列。如果序列包含的元素超过100000个,那么你的代码肯定会失败。今后请坚持使用理智的大括号样式。你的代码以前是无法读取的。另外,我们能得到提示吗?你能提供一个失败的测试用例吗?您的代码到底出了什么问题?@reousasteron这是任务描述的一部分。只是用作序列结束的标志,因为它的长度未知。是的,如果你把它拆下来就完全可以了it@Barry不幸的是,我不知道哪里出了问题,也没有任何测试用例的例子。我把它发送到我的课程的在线测试系统,它只说它在测试8中失败,并且给出了一个错误的答案。你假设序列的长度最多为100000。为什么?正如gnasher729的回答所示,您不需要分配一个数组来存储整个序列。如果序列包含超过100000个元素,那么您的代码肯定会失败。很好,但没有gnasher729优雅的解决方案那么有效,因为