【问题标题】:Increment/Decrement operation to make Greatest common divisor as K使最大公约数为 K 的递增/递减操作
【发布时间】:2017-12-09 14:04:35
【问题描述】:

给定一个大小为 N 的数组。

此外,我们还提供了可以将数组的任何元素递增/递减 1 的操作。

我们的目标是使所有元素的 GCD(最大公约数)在最少的操作数中等于给定数 K。

因此,我们需要找到所需的最少操作数。

示例:假设 N=3 且数组为 [4,5,6] 且 K=5 则此处的答案为 2。 我们可以通过在一次操作中减小 6 的值并在第二次操作中将值增加 4 到 5 来将 GCD 设为 5。

我的做法: 我们的最终目标是这样的:

[x1 * k,x2 * k,....x3 ∗ k],其中 gcd(x1,x2....xn)=1 (xi ∗ k 是我们替换数组元素的位置位置与)

在单独的数组 DP[i][j] 中维护状态,其中 DP[i][j] = 使 [x1,x2...xi] 的 gcd 等于 j 所需的最少操作。

答案将是 DP[N][1],其中 N 是数组的大小。

但是由于这种方法显然取决于元素的范围,并且所有元素的范围都可以达到 1000000。此外,N、K 也可以达到 1000000。

有什么更好的方法来解决这个问题。 ?

【问题讨论】:

  • 欢迎来到 Stack Overflow。家庭作业类型的问题是可以的,但请尝试问一些比“解决这个问题有什么更好的方法?”更具体的问题
  • 输入或输出是否允许负值?
  • @Airhead 当然。我第一次 :) 感谢您的建议
  • @STF 仅限非负正整数
  • 有专门的网页供新手使用。在这里阅读:stackoverflow.com/help/asking

标签: c++ algorithm dynamic-programming


【解决方案1】:

这个问题是在hackerearth的一些公司招聘挑战中被问到的。我能够通过示例测试用例和我自己的一些测试用例,但不能通过任何在线法官测试用例。这是我的方法:

    def gcd(a,b):
    if b>a:
        a,b = b,a
    while b:
        a,b = b,a%b
    return a 
t = int(input())
for i in range(t):
    k,n = map(int,input().split())
    arr = [int(x) for x in input().split()]
    ops = 0
    n1 = arr[0]
    n2 = arr[1]
    g = gcd(n1,n2)
    if g!=k:
        i,j = n1%k,n2%k
        if i and j:
            ops = min(i,k-i)+min(j,k-j)
        else:
            if i:
                ops = min(k-i,i)
            elif j:
                 ops = min(k-j,j)
    for i in range(2,n):
        g = gcd(k,arr[i])
        if g!=k:
            j = arr[i]%k
            ops += min(k-j,j)
    print(ops)

其次,我的想法是遍历数组并找出转换 arr[i]%k==0 需要多少步骤并找到其中的最小值并添加到答案中,这基本上也是我的第一个方法。

t = int(input())
for i in range(t):
    k,n = map(int,input().split())
    arr = [int(x) for x in input().split()]
    ops = 0

    for num in arr:
        rem = num%k
        if rem>0:
            ops+=min(rem,k-rem)
    print(ops)

【讨论】:

    【解决方案2】:

    以下是我的代码在 java 中为我通过了所有测试用例

    Scanner s = new Scanner(System.in);
        int t = s.nextInt();
        while (t > 0) {
            int k = s.nextInt();
            int n = s.nextInt();
            int[] nums = new int[n];
            for (int i = 0; i < n; i++) {
                nums[i] = s.nextInt();
            }
            long opt = 0;
            for (int num : nums) {
                if (num == k) {
                    continue;
                }
                if (num < k) {
                    opt += k - num;
                } else {
                    int rem = num % k;
                    if (rem > 0) {
                        opt += Math.min(rem, k - rem);
                    }
                }
            }
            System.out.println(String.valueOf(opt));
            t--;
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-01-02
      • 2021-12-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-17
      • 1970-01-01
      相关资源
      最近更新 更多