当前位置: 首页 > 知识库问答 >
问题:

如何计算使序列的所有元素彼此相等所需的最小操作数

经和洽
2023-03-14
The problem is from a programming competition.

给定两个序列A(a1, a2, a3,... an)B(b1, b2, b3,... bns),长度相同N。在每个步骤中,您可以设置ai=ai-biifai

例如

A = {5, 7, 10, 5, 15} 
B = {2, 2, 1, 3, 5}

在上述示例中,使A中的所有元素彼此相等所需的最小步骤数为8

A = {5, 15, 25, 35, 45, 90, 100}
B = {5, 5, 5, 5, 5, 5, 5}

在上述示例中,使A中的所有元素彼此相等所需的最小步骤数为56

请注意,如果无法使序列A的所有元素彼此相等,则打印-1

例如

A = {5, 6}  
B = {4, 3}

在上述情况下,答案是-1,因为不可能使A的所有元素彼此相等。

A = {5, 15, 25, 35, 45, 90, 100}
B = {5, 5, 5, 5, 5, 0, 5}

在上述情况下,答案是-1,因为不可能使A的所有元素彼此相等。

有谁能帮我有效地解决这个问题吗?


共有2个答案

章学义
2023-03-14

在我看来,有两种方法可以解决它。

  1. 带有一些逻辑的迭代算法(我将用Python实现)
  2. 你可以使用集合(感觉像是作弊)

作者可能想让你这样做:

每一次我们都会尝试用列表中的所有其他项目达到列表的最小值(或更低)。如果所有的项目都是相同的,我们停止并返回成功,否则我们继续前进。如果一些项目低于0,我们停止。

import math

num_of_nums = int(input())

a_s = list(map(int, input().split()))
b_s = list(map(int, input().split()))

operations = 0
m = min(a_s)
while not all([a_s[0] == tmp for tmp in a_s]):
    if m < 0:
        print(-1)
        exit(0)
    for i, (a, b) in enumerate(zip(a_s, b_s)):
        if b == 0 and m != a:
            print(-1)
            exit(0)
        elif b == 0 and m == a:
            continue

        operations_to_min = int(math.ceil((a - m) / b))
        operations += operations_to_min
        a_s[i] = a - operations_to_min * b
    m = min(a_s)
print(operations)

这种方式:

读取输入后,我们创建了一组数字,这些数字可以通过从a中减少每个b来创建,因此对于所提供的示例,我们得到:

[{1, 3, 5}, {1, 3, 5, 7},...

现在我们找到交集,并从中取最大值
找到该数字后,我们计算每个ab对达到该数字的操作数。

import functools
num_of_nums = int(input())

a_s = list(map(int, input().split()))
b_s = list(map(int, input().split()))

sets = [set([a - b * i for i in range(a // b + 1 if b > 0 else 1)]) for a, b in zip(a_s, b_s)]
res = functools.reduce(lambda a, b: a & b, sets)

if len(res) > 0:
    biggest_num = max(res)
    operations = 0
    for a, b in zip(a_s, b_s):
        if b > 0:
            operations += (a - biggest_num) // b
    print(operations)
else:
    print(-1)
芮琛
2023-03-14

目标不能大于A中最小的元素。如果mA中最小元素的索引,则目标也必须是值A[m]-k*B[m](非负整数k)之一。因为可能存在A中最小元素的重复,每个元素都有不同的b,为了简化,我们可以尝试所有等于或小于min(A)的目标。

我们在一个下降循环中尝试它们,因为显然,最高有效的一个将采取最少的步骤到达。有效性检查必须适用于所有(a,b)对,给定候选目标t

(a - t) mod b == 0

例子:

A = {5, 7, 10, 5, 15}
B = {2, 2, 1, 3, 5}

t = 5

a's:

 5: 5 == 5
 7: (7 - 5) mod 2 == 0
10: (10 - 5) mod 1 == 0
 5: 5 == 5
15: (15 - 5) mod 5 == 0

JavaScript代码:

function f(A, B){
  const n = A.length;
  const m = Math.min(...A);
  let result;
  
  for (let t=m; t>=0; t--){
    result = 0;
    
    for (let i=0; i<n; i++){
      if ((A[i] - t) % B[i] == 0){
        result = result + (A[i] - t) / B[i];
        
      } else {
        result = -1;
        break;
      }
    }
    
    if (result > -1)
      return result;
  }
  
  return result;
}

var ABs = [
  [[5, 7, 10, 5, 15],
   [2, 2, 1, 3, 5]],

  [[5, 6],
   [4, 3]]
];

for (let [A, B] of ABs){
  console.log(`A: ${ A }`);
  console.log(`B: ${ B }`);
  console.log(f(A, B));
  console.log('');
}
 类似资料:
  • 我正在阅读这个问题的极客为极客网站。

  • 我看到一个问题,要求它找到所有相邻子阵列的最小值。例如,对于数组A=[1,2,3],答案将是一个包含[1,2,3,1,2,1]的数组B<怎么做- 我所做的是,构建了一个段树,但是它不包含所有连续子数组的最小值。 我也不认为我可以使用“脱钩”,因为我不必在特定长度的子数组中找到最小值。 那么,我如何获得所有连续子阵列(B阵列)的最小值?

  • 我最近遇到了一个编码面试问题,似乎找不到答案。问题是这样的。 给定一个整数数组,编写一个函数,返回组织数组所需的最小交换,以便每个相邻元素的差值小于或等于K。 例如 它应该返回1的原因是,通过交换40和30,数组将满足给定的语句,即所有相邻元素之间的间距应在20以内。 我确实试着在谷歌上搜索答案,我想我在其他算法助手网站上找到了一些答案,但无法找到我问题的答案。失败的测试用例有一个数组和,它们应该

  • 我想知道是否有更好的(或只是其他)方法来获得进入流的终端操作的所有项目的计数,而不是以下方法: 其中给出了该阶段处理项目的实际计数。 我故意跳过了终端操作,因为这可能会在<代码>之间发生变化。forEach,或。收集。我确实知道。已经开始计数了,但只有我交换了一个

  • 1.索引x处元素可以在一次移动中直接移动到x+1,x+2位置或x-1,x-2位置,之后移动计数将增加。 例如,在数组中,最小移动将为31: 索引4处的所有8个元素可以在总共16次移动中移动到索引0(因为所有8个元素都需要2次移动)。移动:16. 索引5中的3个元素可以在3步中移动到索引3(3个元素每步移动1步),索引5中剩余的5个元素可以在10步中移动到索引2(5个元素每步移动2步,所以总共移动1

  • 我有一个pyspark数据框,在这里我可以找到每列的最小/最大值和最小/最大值计数。我可以使用: 我希望在同一数据帧中也有最小/最大值的计数。我需要的具体输出: …|col|n|col|m| …|xn | xm |。。。最小值(col(coln)) 计数(col_n==xn)|计数(col_m==xm)|。。。