📜  最多可将光线从下往右传输的镜子

📅  最后修改于: 2022-05-13 01:57:23.660000             🧑  作者: Mango

最多可将光线从下往右传输的镜子

给出了一个方阵,其中每个单元代表一个空白或一个障碍物。我们可以在空白位置放置镜子。所有镜子都将位于 45 度角,即如果路径中没有障碍物,它们可以将光线从底部传输到右侧。
在这个问题中,我们需要计算可以在方阵中放置多少这样的镜子,这些镜子可以将光线从底部传输到右侧。
例子:

Output for above example is 2.

In above diagram, mirror at (3, 1) and (5, 5) are able
to send light from bottom to right so total possible 
mirror count is 2.

我们可以通过检查这些镜子在矩阵中的位置来解决这个问题,可以将光线从底部传输到右侧的镜子在其路径中不会有任何障碍,即
如果索引 (i, j) 处有镜子,则
对于所有 k, i < k <= N 在索引 (k, j) 处不会有障碍物
对于所有 k,在索引 (i, k) 处不会有障碍物,j < k <= N
记住以上两个方程,我们可以在给定矩阵的一次迭代中找到每一行的最右边障碍物,并且我们可以在给定矩阵的另一次迭代中找到每一列的最底部障碍物。将这些索引存储在单独的数组中后,我们可以在每个索引处检查它是否满足无障碍条件,然后相应地增加计数。
下面是上述概念的实现解决方案,它需要 O(N^2) 时间和 O(N) 额外空间。

C++
// C++ program to find how many mirror can transfer
// light from bottom to right
#include 
using namespace std;
 
// method returns number of mirror which can transfer
// light from bottom to right
int maximumMirrorInMatrix(string mat[], int N)
{
    // To store first obstacles horizontally (from right)
    // and vertically (from bottom)
    int horizontal[N], vertical[N];
 
    // initialize both array as -1, signifying no obstacle
    memset(horizontal, -1, sizeof(horizontal));
    memset(vertical, -1, sizeof(vertical));
 
    // looping matrix to mark column for obstacles
    for (int i=0; i=0; j--)
        {
            if (mat[i][j] == 'B')
                continue;
 
            // mark rightmost column with obstacle
            horizontal[i] = j;
            break;
        }
    }
 
    // looping matrix to mark rows for obstacles
    for (int j=0; j=0; i--)
        {
            if (mat[i][j] == 'B')
                continue;
 
            // mark leftmost row with obstacle
            vertical[j] = i;
            break;
        }
    }
 
    int res = 0; // Initialize result
 
    // if there is not obstacle on right or below,
    // then mirror can be placed to transfer light
    for (int i = 0; i < N; i++)
    {
        for (int j = 0; j < N; j++)
        {
            /* if i > vertical[j] then light can from bottom
               if j > horizontal[i] then light can go to right */
            if (i > vertical[j] && j > horizontal[i])
            {
                /* uncomment this code to print actual mirror
                   position also
                cout << i << " " << j << endl; */
                res++;
            }
        }
    }
 
    return res;
}
 
//  Driver code to test above method
int main()
{
    int N = 5;
 
    //  B - Blank     O - Obstacle
    string mat[N] = {"BBOBB",
                     "BBBBO",
                     "BBBBB",
                     "BOOBO",
                     "BBBOB"
                    };
 
    cout << maximumMirrorInMatrix(mat, N) << endl;
 
    return 0;
}


Java
// Java program to find how many mirror can transfer
// light from bottom to right
import java.util.*;
 
class GFG
{
 
    // method returns number of mirror which can transfer
    // light from bottom to right
    static int maximumMirrorInMatrix(String mat[], int N)
    {
        // To store first obstacles horizontally (from right)
        // and vertically (from bottom)
        int[] horizontal = new int[N];
        int[] vertical = new int[N];
 
        // initialize both array as -1, signifying no obstacle
        Arrays.fill(horizontal, -1);
        Arrays.fill(vertical, -1);
         
        // looping matrix to mark column for obstacles
        for (int i = 0; i < N; i++)
        {
            for (int j = N - 1; j >= 0; j--)
            {
                if (mat[i].charAt(j) == 'B')
                {
                    continue;
                }
 
                // mark rightmost column with obstacle
                horizontal[i] = j;
                break;
            }
        }
 
        // looping matrix to mark rows for obstacles
        for (int j = 0; j < N; j++)
        {
            for (int i = N - 1; i >= 0; i--)
            {
                if (mat[i].charAt(j) == 'B')
                {
                    continue;
                }
 
                // mark leftmost row with obstacle
                vertical[j] = i;
                break;
            }
        }
 
        int res = 0; // Initialize result
 
        // if there is not obstacle on right or below,
        // then mirror can be placed to transfer light
        for (int i = 0; i < N; i++)
        {
            for (int j = 0; j < N; j++)
            {
                /* if i > vertical[j] then light can from bottom
                if j > horizontal[i] then light can go to right */
                if (i > vertical[j] && j > horizontal[i])
                {
                    /* uncomment this code to print actual mirror
                    position also
                    cout << i << " " << j << endl; */
                    res++;
                }
            }
        }
 
        return res;
    }
 
// Driver code
public static void main(String[] args)
{
    int N = 5;
 
    // B - Blank     O - Obstacle
    String mat[] = {"BBOBB",
        "BBBBO",
        "BBBBB",
        "BOOBO",
        "BBBOB"
    };
 
    System.out.println(maximumMirrorInMatrix(mat, N));
}
}
 
/* This code is contributed by PrinciRaj1992 */


Python3
# Python3 program to find how many mirror can transfer
# light from bottom to right
 
# method returns number of mirror which can transfer
# light from bottom to right
def maximumMirrorInMatrix(mat, N):
 
    # To store first obstacles horizontally (from right)
    # and vertically (from bottom)
    horizontal = [-1 for i in range(N)]
    vertical = [-1 for i in range(N)];
 
    # looping matrix to mark column for obstacles
    for i in range(N):
        for j in range(N - 1, -1, -1):
             
            if (mat[i][j] == 'B'):
                continue;
 
            # mark rightmost column with obstacle
            horizontal[i] = j;
            break;
         
 
    # looping matrix to mark rows for obstacles
    for j in range(N):
         
        for i in range(N - 1, -1, -1):
         
            if (mat[i][j] == 'B'):
                continue;
 
            # mark leftmost row with obstacle
            vertical[j] = i;
            break;
     
    res = 0; # Initialize result
 
    # if there is not obstacle on right or below,
    # then mirror can be placed to transfer light
    for i in range(N):
        for j in range(N):
     
            ''' if i > vertical[j] then light can from bottom
               if j > horizontal[i] then light can go to right '''
            if (i > vertical[j] and j > horizontal[i]):
             
                ''' uncomment this code to print actual mirror
                   position also'''
                res+=1;
             
    return res;
 
 
#  Driver code to test above method
N = 5;
 
#  B - Blank     O - Obstacle
mat = ["BBOBB",
                 "BBBBO",
                 "BBBBB",
                 "BOOBO",
                 "BBBOB"
                ];
 
print(maximumMirrorInMatrix(mat, N));
 
# This code is contributed by rutvik_56.


C#
// C# program to find how many mirror can transfer
// light from bottom to right
using System;
     
class GFG
{
 
    // method returns number of mirror which can transfer
    // light from bottom to right
    static int maximumMirrorInMatrix(String []mat, int N)
    {
        // To store first obstacles horizontally (from right)
        // and vertically (from bottom)
        int[] horizontal = new int[N];
        int[] vertical = new int[N];
 
        // initialize both array as -1, signifying no obstacle
        for (int i = 0; i < N; i++)
        {
            horizontal[i]=-1;
            vertical[i]=-1;
        }
         
        // looping matrix to mark column for obstacles
        for (int i = 0; i < N; i++)
        {
            for (int j = N - 1; j >= 0; j--)
            {
                if (mat[i][j] == 'B')
                {
                    continue;
                }
 
                // mark rightmost column with obstacle
                horizontal[i] = j;
                break;
            }
        }
 
        // looping matrix to mark rows for obstacles
        for (int j = 0; j < N; j++)
        {
            for (int i = N - 1; i >= 0; i--)
            {
                if (mat[i][j] == 'B')
                {
                    continue;
                }
 
                // mark leftmost row with obstacle
                vertical[j] = i;
                break;
            }
        }
 
        int res = 0; // Initialize result
 
        // if there is not obstacle on right or below,
        // then mirror can be placed to transfer light
        for (int i = 0; i < N; i++)
        {
            for (int j = 0; j < N; j++)
            {
                /* if i > vertical[j] then light can from bottom
                if j > horizontal[i] then light can go to right */
                if (i > vertical[j] && j > horizontal[i])
                {
                    /* uncomment this code to print actual mirror
                    position also
                    cout << i << " " << j << endl; */
                    res++;
                }
            }
        }
 
        return res;
    }
 
// Driver code
public static void Main(String[] args)
{
    int N = 5;
 
    // B - Blank     O - Obstacle
    String []mat = {"BBOBB",
        "BBBBO",
        "BBBBB",
        "BOOBO",
        "BBBOB"
    };
 
    Console.WriteLine(maximumMirrorInMatrix(mat, N));
}
}
 
// This code is contributed by Princi Singh


Javascript


输出:

2