📌  相关文章
📜  查询以检查矩阵中是否存在从源到目标由偶数组成的路径

📅  最后修改于: 2021-05-17 20:46:55             🧑  作者: Mango

给定两个由N个整数组成的数组R []C [] ,这样就可以形成尺寸为N x N的矩阵,其索引为(i,j)的元素由(R [i] + C [j])给出两个数组中所有可能的对。给定矩阵Queries [] [] ,每行代表一个{A,B,X,Y}类型的查询,每个查询的任务是检查是否存在从单元格(A,B)( X,Y)是否仅由偶数组成。如果发现是真的,则打印“是” 。否则,打印“否”

注意:对于从当前单元格(i,j)出发的路径唯一可能的移动是(i + 1,j)(i,j + 1)(i – 1,j)(i,j – 1)

例子:

方法:想法是预先计算数组R []C []的前缀和,然后在给定条件下检查有效路径。步骤如下:

  1. 这个想法是仅在R [r]R [r + 1]的奇偶性相同的情况下才从单元(r,c)迭代到(r + 1,c),因为只有一个元素发生变化。
  2. 类似地,对于(r,c)(r,c +1)的列CC的奇偶校验应该相同。
  3. (r – 1,c)(r,c – 1)执行上述操作。
  4. 现在,对于每个查询,通过检查进入如果R []的从r =(分钟(A,B)最大A,B)()的所有元素具有相同的奇偶性,并从C C []中的所有元素=(分(X,Y)max(X,Y))具有相同的奇偶校验。可以通过预先计算元素的奇偶校验前缀总和来在每个查询的O(1)时间中对此进行检查。
  5. 如果以上条件对所有单元格均成立,则打印“是”,否则打印“否”

下面是上述方法的实现:

C++
// C++ program for the above approach
 
#include 
using namespace std;
 
// Function to find whether the path
// exists with all element even or not
void answerQueries(int n, int q,
                vector& a,
                vector& b,
                vector >& Queries)
{
    // Add 0 to beginning to make
    // 1-based-indexing
    a.insert(a.begin(), 0);
    b.insert(b.begin(), 0);
 
    // Change elements based on parity
    // and take prefix sum
 
    // 1 is odd and 0 is even
 
    // Traverse the array R[]
    for (int i = 1; i <= n; i++) {
 
        // Taking & to check parity
        if (a[i] & 1)
            a[i] = 1;
        else
            a[i] = 0;
 
        // Build prefix sum array
        a[i] += a[i - 1];
    }
 
    // Traverse the array C[]
    for (int i = 1; i <= n; i++) {
 
        // Taking & to check parity
        if (b[i] & 1)
            b[i] = 1;
        else
            b[i] = 0;
 
        // Build prefix sum array
        b[i] += b[i - 1];
    }
 
    // Traverse the matrix Queries[][]
    for (int i = 0; i < q; i++) {
 
        int ra = Queries[i][0];
        int ca = Queries[i][1];
        int rb = Queries[i][2];
        int cb = Queries[i][3];
 
        int r2 = max(ra, rb), r1 = min(ra, rb);
        int c2 = max(ca, cb), c1 = min(ca, cb);
 
        // Check if all numbers are of
        // same parity between (r1 to r2)
        if ((a[r2] - a[r1 - 1] == 0)
            || (a[r2] - a[r1 - 1]
                == r2 - r1 + 1)) {
 
            // Check if all numbers are of
            // same parity between (r1 to r2)
            if ((b[c2] - b[c1 - 1] == 0)
                || (b[c2] - b[c1 - 1]
                    == c2 - c1 + 1)) {
 
                // Path exists
                cout << "Yes" << ' ';
                continue;
            }
        }
 
        // No path exists
        cout << "No" << ' ';
    }
}
 
// Driver Code
int main()
{
    // Given N, Q
    int N = 5, Q = 3;
 
    // Given array R[] and C[]
    vector R{ 6, 2, 7, 8, 3 };
    vector C{ 3, 4, 8, 5, 1 };
 
    // Given queries[][]
    vector > Queries{ { 2, 2, 1, 3 },
                                { 4, 2, 4, 3 },
                                { 5, 1, 3, 4 } };
 
    // Function Call
    answerQueries(N, Q, R, C, Queries);
 
    return 0;
}


Java
// Java program for the above approach
import java.util.*;
import java.lang.*;
import java.io.*;
 
class GFG{
     
// Function to find whether the path
// exists with all element even or not
static void answerQueries(int n, int q,
                          int[] a, int[] b,
                          int[][] Queries)
{
     
    // Add 0 to beginning to make
    // 1-based-indexing
    // a[0]=0;
    // b[0]=0;
   
    // Change elements based on parity
    // and take prefix sum
   
    // 1 is odd and 0 is even
   
    // Traverse the array R[]
    for(int i = 1; i <= n; i++)
    {
         
        // Taking & to check parity
        if ((a[i] & 1) != 0)
            a[i] = 1;
        else
            a[i] = 0;
   
        // Build prefix sum array
        a[i] += a[i - 1];
    }
   
    // Traverse the array C[]
    for(int i = 1; i <= n; i++)
    {
         
        // Taking & to check parity
        if ((b[i] & 1) != 0)
            b[i] = 1;
        else
            b[i] = 0;
   
        // Build prefix sum array
        b[i] += b[i - 1];
    }
   
    // Traverse the matrix Queries[][]
    for(int i = 0; i < q; i++)
    {
        int ra = Queries[i][0];
        int ca = Queries[i][1];
        int rb = Queries[i][2];
        int cb = Queries[i][3];
   
        int r2 = Math.max(ra, rb),
            r1 = Math.min(ra, rb);
        int c2 = Math.max(ca, cb),
            c1 = Math.min(ca, cb);
   
        // Check if all numbers are of
        // same parity between (r1 to r2)
        if ((a[r2] - a[r1 - 1] == 0) ||
            (a[r2] - a[r1 - 1] == r2 - r1 + 1))
        {
             
            // Check if all numbers are of
            // same parity between (r1 to r2)
            if ((b[c2] - b[c1 - 1] == 0) ||
                (b[c2] - b[c1 - 1] == c2 - c1 + 1))
            {
                 
                // Path exists
                System.out.print("Yes" + " ");
                continue;
            }
        }
         
        // No path exists
        System.out.print("No" + " ");
    }
}
   
// Driver Code
public static void main (String[] args)
throws java.lang.Exception
{
     
    // Given N, Q
    int N = 5, Q = 3;
     
    // Given array R[] and C[]
    int R[] = { 0, 6, 2, 7, 8, 3 };
    int C[] = { 0, 3, 4, 8, 5, 1 };
     
    // Given queries[][]
    int[][] Queries = { { 2, 2, 1, 3 },
                        { 4, 2, 4, 3 },
                        { 5, 1, 3, 4 }};
                                  
    // Function call
    answerQueries(N, Q, R, C, Queries);
}
}
 
// This code is contributed by bikram2001jha


Python3
# Python3 program for
# the above approach
 
# Function to find whether the path
# exists with all element even or not
def answerQueries(n, q, a, b, Queries):
   
    # Add 0 to beginning to make
    # 1-based-indexing
    # a[0]=0;
    # b[0]=0;
    # Change elements based on parity
    # and take prefix sum
    # 1 is odd and 0 is even
    # Traverse the array R
    for i in range(1, n + 1):
 
        # Taking & to check parity
        if ((a[i] & 1) != 0):
            a[i] = 1;
        else:
            a[i] = 0;
 
        # Build prefix sum array
        a[i] += a[i - 1];
 
    # Traverse the array C
    for i in range(1, n + 1):
 
        # Taking & to check parity
        if ((b[i] & 1) != 0):
            b[i] = 1;
        else:
            b[i] = 0;
 
        # Build prefix sum array
        b[i] += b[i - 1];
 
    # Traverse the matrix Queries
    for i in range(0, q):
        ra = Queries[i][0];
        ca = Queries[i][1];
        rb = Queries[i][2];
        cb = Queries[i][3];
 
        r2 = max(ra, rb); r1 = min(ra, rb);
        c2 = max(ca, cb); c1 = min(ca, cb);
 
        # Check if all numbers are of
        # same parity between (r1 to r2)
        if ((a[r2] - a[r1 - 1] == 0) or
            (a[r2] - a[r1 - 1] == r2 - r1 + 1)):
 
            # Check if all numbers are of
            # same parity between (r1 to r2)
            if ((b[c2] - b[c1 - 1] == 0) or
                (b[c2] - b[c1 - 1] == c2 - c1 + 1)):
               
                # Path exists
                print("Yes", end = " ");
                continue;
 
        # No path exists
        print("No", end = " ");
 
# Driver Code
if __name__ == '__main__':
   
    # Given N, Q
    N = 5;
    Q = 3;
 
    # Given array R and C
    R = [0, 6, 2, 7, 8, 3];
    C = [0, 3, 4, 8, 5, 1];
 
    # Given queries
    Queries = [[2, 2, 1, 3],
               [4, 2, 4, 3],
               [5, 1, 3, 4]];
 
    # Function call
    answerQueries(N, Q, R, C, Queries);
 
# This code is contributed by shikhasingrajput


C#
// C# program for
// the above approach
using System;
class GFG{
     
// Function to find whether the path
// exists with all element even or not
static void answerQueries(int n, int q,
                          int[] a, int[] b,
                          int[,] Queries)
{
  // Add 0 to beginning to make
  // 1-based-indexing
  // a[0]=0;
  // b[0]=0;
 
  // Change elements based on parity
  // and take prefix sum
 
  // 1 is odd and 0 is even
 
  // Traverse the array R[]
  for(int i = 1; i <= n; i++)
  {
    // Taking & to check parity
    if ((a[i] & 1) != 0)
      a[i] = 1;
    else
      a[i] = 0;
 
    // Build prefix sum array
    a[i] += a[i - 1];
  }
 
  // Traverse the array C[]
  for(int i = 1; i <= n; i++)
  {
    // Taking & to check parity
    if ((b[i] & 1) != 0)
      b[i] = 1;
    else
      b[i] = 0;
 
    // Build prefix sum array
    b[i] += b[i - 1];
  }
 
  // Traverse the matrix Queries[,]
  for(int i = 0; i < q; i++)
  {
    int ra = Queries[i, 0];
    int ca = Queries[i, 1];
    int rb = Queries[i, 2];
    int cb = Queries[i, 3];
 
    int r2 = Math.Max(ra, rb),
        r1 = Math.Min(ra, rb);
    int c2 = Math.Max(ca, cb),
        c1 = Math.Min(ca, cb);
 
    // Check if all numbers are of
    // same parity between (r1 to r2)
    if ((a[r2] - a[r1 - 1] == 0) ||
        (a[r2] - a[r1 - 1] == r2 - r1 + 1))
    {
      // Check if all numbers are of
      // same parity between (r1 to r2)
      if ((b[c2] - b[c1 - 1] == 0) ||
          (b[c2] - b[c1 - 1] == c2 - c1 + 1))
      {
        // Path exists
        Console.Write("Yes" + " ");
        continue;
      }
    }
 
    // No path exists
    Console.Write("No" + " ");
  }
}
   
// Driver Code
public static void Main(String[] args)
{
  // Given N, Q
  int N = 5, Q = 3;
 
  // Given array R[] and C[]
  int []R = {0, 6, 2, 7, 8, 3};
  int []C = {0, 3, 4, 8, 5, 1};
 
  // Given [,]queries
  int[,] Queries = {{2, 2, 1, 3},
                    {4, 2, 4, 3},
                    {5, 1, 3, 4}};
 
  // Function call
  answerQueries(N, Q, R, C, Queries);
}
}
 
// This code is contributed by Princi Singh


输出
Yes Yes No 

时间复杂度: O(N + Q)
辅助空间: O(1)