任务 - 数字的最大K-乘积
时间限制:1
记忆限制:64 M
给定一系列整数N(1≤N≤10May,| A i |≤2.109)和K的数目(1≤K≤N)。查找产品最大的K序列号。
输入数据:
第一行包含两个整数N和K.
在第二行中列出了序列A的N个元素。
输出数据:
获得最大产品。所以答案可能非常大,输出模10 ^ 9 + 7。
实施例
输入数据的结果
3 2
-2 -3 3
答案 - 6
以下是我的尝试。这是一个错误,这是我不知道的。你能否帮我在决定中找错?
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <vector>
using namespace std;
typedef vector<int> v1;
const int mod = 1000000007;
int n, k, pos1 = 0, pos2 = 0, negative = 0;
long long res = 1;
void QuickSort(v1 &a, int l, int r) {
int i = l, j = r, pivot = abs(a[l + ((r - l) >> 1)]);
do {
while (abs(a[i]) < pivot) i++;
while (abs(a[j]) > pivot) j--;
if (i <= j) {
int temp = a[i];
a[i++] = a[j];
a[j--] = temp;
}
} while (i < j);
if (l < j) QuickSort(a, l, j);
if (i < r) QuickSort(a, i, r);
}
long long product(v1 &a, v1 &b, int q, int j, char flag) {
long long res = 1; int temppos;
if (flag == 0 && j) {
temppos = b[pos1];
b[pos1] = j;
}
if (flag == 1 && q) {
temppos = b[pos2];
b[pos2] = q;
}
if (!pos2 && (k & 1)) {
for (int i = 1; i <= k; i++)
res = (long long)((res % mod)*1ll*(a[i] % mod)) % mod;
} else {
for (int i = 1; b[i] != 0; i++)
res = (long long)((res % mod)*1ll*(a[b[i]] % mod)) % mod;
}
if (flag == 0 && j) b[pos1] = temppos;
if (flag == 1 && q) b[pos2] = temppos;
return res;
}
int main()
{
v1 a(100002, 0);
v1 b(100002, 0); //index multiplied to the elements
cin >> n >> k;
for (int i = 1; i <= n; i++) cin >> a[i];
QuickSort(a, 1, n);
for (int i = n, j = 1; i > n - k; i--) {
b[j] = i;
if (a[i] < 0) {
pos1 = j; //index last positive number
negative++; //increase the counter negative numbers
}
else pos2 = j; //index last positive number
j++;
}
int j = n - k, q = j;
if (negative & 1) { //If an odd number of negative numbers
while (j > 0 && a[j] < 0) j--;
while (q > 0 && a[q] > 0) q--;
res = max(product(a, b, q, j, 0), product(a, b, q, j, 1));
} else res = product(a, b, q, j, 3);
cout << res << endl;
cin >> res;
return 0;
}
答案 0 :(得分:0)
首先:你的代码非常密集和混乱,所以我会在这里给出自己的方法和思考过程。
所以我的第一个想法是关于所有输入整数都是正数的情况。调用我们的源数组(包含N个整数的数组)A。
这需要O(KN)时间,所以如果K比O(lg(N))慢,那么它比你的快速排序更快,也更简单。你可以通过使用树或堆来存储B来改善O(N lg(K))的时间限制,但这超出了职责范围。
我的解决方案的问题是该问题将负数作为输入。现在,如果通过“Answer - 6”表示“答案是-6 = -2 * 3”,并且您要求的是最大幅度的产品,那么您需要做的就是获取上面每个输入数字的大小程序。但是你的代码表明你的意思是“答案是6 = -2 * -3”,在这种情况下,事情要复杂得多。
看看,如果最大乘积包含两个(或偶数)负整数(如(6 = -2 * -3)的例子),我的方法将不起作用,因为排序程序吸收负数在列表的底部。
相反,我们需要做的是保留三个数组:A,我们的输入数组; B,到目前为止遇到的K 最大正数字的数组;和C,一个最小负数的数组(以避免混淆:在列表-2 -3 -4中,两个最小的负数是-3和-4)到目前为止遇到的数字。
当我们使用类似于上面的例程提取B和C时,我们需要将它们组合起来。我能想到的最好的方法是首先对B和C进行排序,然后
这需要O(K ^ 2)或左右,你可以再用一个更智能的方法来加快速度(比如当你插入的负数对的乘积小于产品时停止替换)您正在替换的正数对),但这是我能想到的最清楚的数字。