gpt4 book ai didi

c++ - 最快的算法计算数组中 3 个长度 AP 的数量

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:24:43 24 4
gpt4 key购买 nike

我要解决this CodeChef 挑战:

假设我们有一个包含 N(范围为 100,000)个元素的数组 A。我们要找到所有 3 个这样的元素对的计数 1<=Ai,Aj,Ak<=30,000 使得

Aj-Ai = Ak- Aj and i < j < k

换句话说,Ai、Aj、Ak 处于等差级数。例如数组:

9 4 2 3 6 10 3 3 10


所以 AP 是:

{2,6,10},{9,6,3},{9,6,3},{3,3,3},{2,6,10} 


所以要求的答案是 5。

我的方法

我尝试的是取名为 past 和 right 的 30,000 个长数组。最初右边包含每个 1-30,000 元素的计数。

如果我们在第i个位置,past存储i之前数组值的计数,right存储i之后数组的计数。我只是循环查找数组中所有可能的公差。这是代码:

right[arr[1]]--;

for(i=2;i<=n-1;i++)
{
past[arr[i-1]]++;
right[arr[i]]--;
k=30000 - arr[i];
if(arr[i] <= 15000)
k=arr[i];
for(d=1;d<=k;d++)
{
ans+= right[arr[i] + d]*past[arr[i]-d] + past[arr[i] + d]*right[arr[i]-d];
}
ans+=past[arr[i]]*right[arr[i]];
}



但这让我超出了时间限制。请提供更好的算法。

最佳答案

如果您第一次遍历列表并仅提取可能有 3 项 AP 的数字对(差异为 0 mod 2),则可以大大缩短执行时间。然后在这些对之间迭代。

伪 C++-y 代码:

// Contains information about each beginning point
struct BeginNode {
int value;
size_t offset;
SortedList<EndNode> ends; //sorted by EndNode.value
};

// Contains information about each class of end point
struct EndNode {
int value;
List<size_t> offsets; // will be sorted without effort due to how we collect offsets
};

struct Result {
size_t begin;
size_t middle;
size_t end;
};

SortedList<BeginNode> nodeList;
foreach (auto i : baseList) {
BeginNode begin;
node.value = i;
node.offset = i's offset; //you'll need to use old school for (i=0;etc;i++) with this
// baseList is the list between begin and end-2 (inclusive)
foreach (auto j : restList) {
// restList is the list between iterator i+2 and end (inclusive)
// we do not need to consider i+1, because not enough space for AP
if ((i-j)%2 == 0) { //if it's possible to have a 3 term AP between these two nodes
size_t listOffset = binarySearch(begin.ends);
if (listOffset is valid) {
begin.ends[listOffset].offsets.push_back(offsets);
} else {
EndNode end;
end.value = j;
end.offsets.push_back(j's offset);
begin.ends.sorted_insert(end);
}
}
}
if (begin has shit in it) {
nodeList.sorted_insert(begin);
}
}
// Collection done, now iterate over collection

List<Result> res;
foreach (auto node : nodeList) {
foreach (auto endNode : node.ends) {
foreach (value : sublist from node.offset until endNode.offsets.last()) {
if (value == average(node.value, endNode.value)) {
// binary_search here to determine how many offsets in "endNode.offsets" "value's offset" is less than.
do this that many times:
res.push_back({node.value, value, endNode.value});
}
}
}
}

return res;

关于c++ - 最快的算法计算数组中 3 个长度 AP 的数量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13240330/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com