📌  相关文章
📜  使给定矩阵的至少一行为素数的所有元素所需的最少操作数

📅  最后修改于: 2021-05-17 22:39:07             🧑  作者: Mango

给定大小为N * M的矩阵mat [] [] ,任务是找到使给定矩阵至少一行的所有元素为素数所需的最小操作数。在每个操作中,根据以下条件合并矩阵的任意两行:

  • 如果矩阵两行的k元素(即mat [i] [k]mat [j] [k]是素数或复合数),则合并行的k元素包含min(mat [i] [ k],mat [j] [k])
  • 否则,合并行的k元素包含素数元素。

如果不可能将一行的所有元素都作为质数,则打印-1

例子:

方法:使用带位掩码的动态编程可以解决该问题。请按照以下步骤解决问题:

  • 初始化变量,例如bitmask ,如果行的i列不是素数,则将bitmask的i存储在其中。
  • 初始化一个数组,例如dp [] ,其中dp [X]存储在一行中获取X个质数的计数所需的最小操作数。
  • 遍历矩阵的每一行,并更新每一行的位掩码值。使用变量j迭代[[1 <<(M – 1)),0]范围,并更新dp [j |位掩码]min(dp [j |位掩码],dp [j] + 1)
  • 最后,检查连续获取M个质数所需的最小操作数是否大于N ,即,检查dp [(1 <<(M – 1))]是否大于N。如果发现是真的,则打印-1
  • 否则,打印(dp [(1 <<(M – 1))] – 1)的值

下面是上述方法的实现。

Java
// Java program to implement
// the above approach
 
import java.io.*;
import java.util.*;
 
class GFG {
 
    // Function to generate all prime
    // numbers using Sieve of Eratosthenes
    private static boolean[] prime;
 
    // Function to check if a number
    // is prime or not
    private static void sieve(int n)
    {
        // prime[i]: Check if i is a
        // prime number or not
        prime = new boolean[n + 1];
 
        // Initialize prime[]
        // array to true
        Arrays.fill(prime, true);
 
        // Iterate over the range
        // [2, sqrt(n)]
        for (int p = 2; p * p <= n;
             p++) {
 
            // If p is a prime number
            if (prime[p] == true) {
 
                // Mark all multiples
                // of i to false
                for (int i = p * p;
                     i <= n; i += p)
 
                    // Update i
                    prime[i] = false;
            }
        }
    }
 
    // Function to find minimum operations
    // to make all elements of at least one
    // row of the matrix as prime numbers
    private static int MinWays(int[][] a,
                               int n, int m)
    {
        // dp[i]: Stores minimum operations
        // to get i prime numbers in a row
        int[] dp = new int[1 << m];
 
        // Initialize dp[] array
        // to (n + 1)
        Arrays.fill(dp, n + 1);
 
        // Traverse the array
        for (int i = 0; i < a.length;
             i++) {
 
            // Stores count of prime
            // numbers in a i-th row
            int bitmask = BitMask(a[i]);
 
            // Iterate over the range
            // [(1 << m) - 1, 0]
            for (int j = (1 << m) - 1;
                 j >= 0; j--) {
 
                // If a row exist which
                // contains j prime numbers
                if (dp[j] != n + 1) {
 
                    // Update dp[j | bitmask]
                    dp[j | bitmask]
                        = Math.min(dp[j | bitmask],
                                   dp[j] + 1);
                }
            }
 
            // Update dp[bitmask]
            dp[bitmask] = 1;
        }
 
        // Return minimum operations to get a row
        // of the matrix with all prime numbers
        return (dp[(1 << m) - 1] - 1) == (n + 1)
            ? -1
            : (dp[(1 << m) - 1] - 1);
    }
 
    // Function to count prime
    // numbers in a row
    private static int BitMask(int[] a)
    {
        // i-th bit of bitmask check if
        // i-th column is a prime or not
        int bitmask = 0;
 
        // Travere the array
        for (int i = 0; i < a.length;
             i++) {
 
            // if a[i] is a prime number
            if (prime[a[i]]) {
 
                // Update bitmask
                bitmask |= (1 << i);
            }
        }
        return bitmask;
    }
 
    // Driver Code
    public static void main(String[] args)
    {
        int[][] mat = { { 4, 6, 5, 8 },
                        { 2, 9, 12, 14 },
                        { 32, 7, 18, 16 },
                        { 12, 4, 35, 17 } };
 
        // Stores count of columns
        // in the matrix
        int m = mat[0].length;
 
        // Stores length
        int n = mat.length;
 
        // Calulate all prime numbers in
        // range [1, max] using sieve
        int max = 10000;
        sieve(max);
 
        // Function Call
        System.out.println(
            MinWays(mat, n, m));
    }
}


Python3
# Python 3 program to implement
# the above approach
from math import sqrt
 
# Function to generate all prime
# numbers using Sieve of Eratosthenes
prime = [True for i in range(10001)]
 
# Function to check if a number
# is prime or not
def sieve(n):
   
    # prime[i]: Check if i is a
    # prime number or not
    global prime
 
    # Iterate over the range
    # [2, sqrt(n)]
    for p in range(2,int(sqrt(10000)) + 1, 1):
       
        # If p is a prime number
        if (prime[p] == True):
           
            # Mark all multiples
            # of i to false
            for i in range(p * p, 10001, p):
               
                # Update i
                prime[i] = False
 
# Function to find minimum operations
# to make all elements of at least one
# row of the matrix as prime numbers
def MinWays(a, n, m):
   
    # dp[i]: Stores minimum operations
    # to get i prime numbers in a row
    dp = [n + 1 for i in range(1 << m)]
 
    # Traverse the array
    for i in range(len(a)):
       
        # Stores count of prime
        # numbers in a i-th row
        bitmask = BitMask(a[i])
 
        # Iterate over the range
        # [(1 << m) - 1, 0]
        j = (1 << m) - 1
        while(j >= 0):
           
            # If a row exist which
            # contains j prime numbers
            if (dp[j] != n + 1):
               
                # Update dp[j | bitmask]
                dp[j | bitmask] = min(dp[j | bitmask],dp[j] + 1)
            j -= 1
 
        # Update dp[bitmask]
        dp[bitmask] = 1
 
    # Return minimum operations to get a row
    # of the matrix with all prime numbers
    if (dp[(1 << m) - 1] - 1) == (n + 1):
        return -1
    else:
        return (dp[(1 << m) - 1] - 1)
 
# Function to count prime
# numbers in a row
def BitMask(a):
    global prime
     
    # i-th bit of bitmask check if
    # i-th column is a prime or not
    bitmask = 0
 
    # Travere the array
    for i in range(len(a)):
       
        # if a[i] is a prime number
        if (prime[a[i]]):
           
            # Update bitmask
            bitmask |= (1 << i)
    return bitmask
 
# Driver Code
if __name__ == '__main__':
    mat = [[4, 6, 5, 8],
           [2, 9, 12, 14],
           [32, 7, 18, 16],
           [12, 4, 35, 17]]
 
    # Stores count of columns
    # in the matrix
    m = len(mat[0])
 
    # Stores length
    n = len(mat)
 
    # Calulate all prime numbers in
    # range [1, max] using sieve
    max = 10000
    sieve(max)
 
    # Function Call
    print(MinWays(mat, n, m))
     
    # Thhis code is contributed by SURENDRA_GANGWAR.


C#
// C# program to implement
// the above approach
using System;
 
public class GFG
{
 
  // Function to generate all prime
  // numbers using Sieve of Eratosthenes
  private static bool[] prime;
 
  // Function to check if a number
  // is prime or not
  private static void sieve(int n)
  {
    // prime[i]: Check if i is a
    // prime number or not
    prime = new bool[n + 1];
 
    // Initialize prime[]
    // array to true
    for (int i = 0; i < prime.Length; i++)
      prime[i] = true;
 
    // Iterate over the range
    // [2, sqrt(n)]
    for (int p = 2; p * p <= n;
         p++) {
 
      // If p is a prime number
      if (prime[p] == true)
      {
 
        // Mark all multiples
        // of i to false
        for (int i = p * p;
             i <= n; i += p)
 
          // Update i
          prime[i] = false;
      }
    }
  }
 
  // Function to find minimum operations
  // to make all elements of at least one
  // row of the matrix as prime numbers
  private static int MinWays(int[,] a,
                             int n, int m)
  {
    // dp[i]: Stores minimum operations
    // to get i prime numbers in a row
    int[] dp = new int[1 << m];
 
    // Initialize []dp array
    // to (n + 1)
    for (int i = 0; i < dp.Length;i++)
    {
      dp[i] = n + 1;
    }
 
    // Traverse the array
    for (int i = 0; i < a.GetLength(0);
         i++)
    {
 
      // Stores count of prime
      // numbers in a i-th row
      int bitmask = BitMask(GetRow(a,i));
 
      // Iterate over the range
      // [(1 << m) - 1, 0]
      for (int j = (1 << m) - 1;
           j >= 0; j--)
      {
 
        // If a row exist which
        // contains j prime numbers
        if (dp[j] != n + 1)
        {
 
          // Update dp[j | bitmask]
          dp[j | bitmask]
            = Math.Min(dp[j | bitmask],
                       dp[j] + 1);
        }
      }
 
      // Update dp[bitmask]
      dp[bitmask] = 1;
    }
 
    // Return minimum operations to get a row
    // of the matrix with all prime numbers
    return (dp[(1 << m) - 1] - 1) == (n + 1)
      ? -1
      : (dp[(1 << m) - 1] - 1);
  }
 
  // Function to count prime
  // numbers in a row
  private static int BitMask(int[] a)
  {
    // i-th bit of bitmask check if
    // i-th column is a prime or not
    int bitmask = 0;
 
    // Travere the array
    for (int i = 0; i < a.Length;
         i++) {
 
      // if a[i] is a prime number
      if (prime[a[i]])
      {
 
        // Update bitmask
        bitmask |= (1 << i);
      }
    }
    return bitmask;
  }
  public static int[] GetRow(int[,] matrix, int row)
  {
    var rowLength = matrix.GetLength(1);
    var rowVector = new int[rowLength];
 
    for (var i = 0; i < rowLength; i++)
      rowVector[i] = matrix[row, i];
 
    return rowVector;
  }
 
  // Driver Code
  public static void Main(String[] args)
  {
    int[,] mat = { { 4, 6, 5, 8 },
                  { 2, 9, 12, 14 },
                  { 32, 7, 18, 16 },
                  { 12, 4, 35, 17 } };
 
    // Stores count of columns
    // in the matrix
    int m = mat.GetLength(0);
 
    // Stores length
    int n = mat.GetLength(1);
 
    // Calulate all prime numbers in
    // range [1, max] using sieve
    int max = 10000;
    sieve(max);
 
    // Function Call
    Console.WriteLine(
      MinWays(mat, n, m));
  }
}
 
// This code is contributed by shikhasingrajput


输出:
3

时间复杂度: O(X * log(log(X))+ N * M * 2 M ),其中X是矩阵的最大元素
辅助空间: O(X + 2 M )