c++ - 找到所有连接对的总和的高效算法

标签 c++ algorithm combinatorics

我参加了 CodeSignal 练习考试,并且能够通过 14/16 测试用例来解决这个问题。您将获得一个 vector 作为输入(整数列表),并且解决方案将很长很长。

最初我只是使用了两个 for 循环的蛮力解决方案,并将当前的 a[i] concat a[j] 添加到运行总数中。但是,我尝试通过使用内存来优化它。我使用 unordered_map 对检查我是否已经计算了 (i,j) 对,如果已经计算,只需返回缓存的结果。即使进行了优化,我仍然没有通过任何额外的测试用例并收到 14/16 的结果。我缺少什么见解或优化?

我发现了类似的在线问题,但是他们的见解似乎不适用于这个特定问题。

例如:Similar Problem

问题:

给定一个正整数数组 a
您的任务是计算每个可能的 concat(a[i], a[j]) 的总和,其中 concat(a[i],a[j]) 是 a[I] 和 a 的字符串表示的串联[j] 分别。

前任:

a = [10,2]
sol = 1344
a[0],a[0] = 1010
a[0],a[1] = 102
a[1],a[0] = 210
a[1],a[1] = 22
sum of above = 1344

代码:
long long concat(int x, int y)
{
  string str = to_string(x)+to_string(y);
  return stoll(str);
}
long long calculateSum(vector<int> a)
{
  unordered_map<pair<int,int>,long long, hash_pair> memo;
  long long total = 0;
  for(int i = 0; i < a.size(); i++)
  {
    for(int j = 0; j < a.size(); j++)
    {
      auto currPair = make_pair(a[i],a[j]);
      auto got = memo.find(currPair);
      //if it's a new combination
      if(currPair == got.end())
      {
        long long res = concat(a[i],a[j]);
        memo.insert(make_pair(currPair,res));
        total += res;
      }
      //we've computed this result before
      else
      {
        total += got->second;
      }
    }
  }
  return total;
}

最佳答案

让我们计算贡献 a_i 整数来回答所有对。有两种情况。 a_i 数为低部分时的第一种情况。当总和是 n * a_i 时回答( n 是总数整数)。第二种情况是高分。然后让我们找到十进制表示法中的所有偏移量。由 k_j 表示为总数整数长度 j(十进制长度)。然后高部分添加回答 k_j * a_i * 10^j 所有值 j ( 1 <= j <= 7 )。知道 k_j 我们可以在线性时间内计算所有数字 a_i 的答案。

关于c++ - 找到所有连接对的总和的高效算法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62397126/

相关文章:

groovy - Groovy 中的真正组合

c++ - 从 `const std::string` 隐式构造 `const char *` 是否有效?

c++ - GLEW 未初始化;抛出 "Missing OpenGL Version"

Java/C++ - 从相机偏航(航向)和俯仰(无滚动)获取 3d 线

algorithm - 如何有效地测试一组(唯一)整数是否属于另一组?

r - 从聚合满足条件的列表中查找 n 个元组

c++ - 右值参数无法在函数重载中解析

java - 如何实现广度优先搜索到一定深度?

algorithm - 编码系统按1的个数排序

c++ - 如何组合来自 std::set 的成对元素?