📜  最大限度地减少单次切割中切割的瓷砖数量

📅  最后修改于: 2021-09-04 11:37:47             🧑  作者: Mango

给定一个二维数组,表示等长瓷砖的宽度和水平,每个水平的总宽度相同,任务是找到可以被穿过所有水平的剑的单次垂直打击切割的最小数量的瓷砖瓷砖。

例子:

方法:这个想法是找到最大数量的间隙,以便如果绘制的垂直线通过这些点,那么它将切割最少数量的瓷砖。请按照以下步骤解决问题:

  • 遍历二维数组tilesStack[][]的每一行。对于每i 行,Map 其前缀和,它表示从最左边的 tile 开始的间隙的距离,并使用 Map 存储每行的前缀和的频率。
  • 找到前缀总和(间隙距离)的最大频率,比如X
  • 最后,打印(length(tilesStack) – X) 的值,它表示通过绘制垂直线切割的最小瓷砖数量。

下面是这个方法的实现。

C++
// C++ program for the above approach
#include
using namespace std;
 
// Function to count the minimum number
// of tiles that gets cut by a single
// vertical strike of a sword
void cutTiles(vector> tilesStack)
{
 
  // Map prefix sum of each row
  // of tilesStack
  map gaps;
 
  // Traverse each row of the tiles
  for(vector tiles:tilesStack)
  {
 
    // Stores distance of gap from
    // left of each row
    int totWidth = 0;
 
    // Excluding the last gap as it will
    // be the edge of the level
    for(int i = 0; i < tiles.size() - 1; i++)
    {
 
      // Update totWidth
      totWidth += tiles[i];
 
      // If gap is already found at
      // this points in previous levels
      gaps[totWidth]++;
    }
  }
 
  // Stores maximum number of 
  // gap from left
  int X = 0;
  for(auto x : gaps)
  {
    X = max(x.second, X);
  }
  cout << tilesStack.size() - X;
}
 
// Driver code
int main()
{
  vector> tilesStack(4);
  tilesStack[0].push_back(2);
  tilesStack[0].push_back(3);
  tilesStack[1].push_back(3);
  tilesStack[1].push_back(2);
  tilesStack[2].push_back(1);
  tilesStack[2].push_back(1);
  tilesStack[2].push_back(1);
  tilesStack[2].push_back(2);
  tilesStack[3].push_back(1);
  tilesStack[3].push_back(1);
  tilesStack[3].push_back(1);
  tilesStack[3].push_back(1);
  tilesStack[3].push_back(1);
 
  // Function Call
  cutTiles(tilesStack);
}
 
// This code is contributed by rutvik_56.


Java
// Java program for the above approach
import java.util.*;
public class GFG
{
 
  // Function to count the minimum number
  // of tiles that gets cut by a single
  // vertical strike of a sword
  static void cutTiles(Vector> tilesStack)
  {
 
    // Map prefix sum of each row
    // of tilesStack
    HashMap gaps = new HashMap<>();
 
    // Traverse each row of the tiles
    for(Vector tiles : tilesStack)
    {
 
      // Stores distance of gap from
      // left of each row
      int totWidth = 0;
 
      // Excluding the last gap as it will
      // be the edge of the level
      for(int i = 0; i < tiles.size() - 1; i++)
      {
 
        // Update totWidth
        totWidth += tiles.get(i);
 
        // If gap is already found at
        // this points in previous levels
        if(gaps.containsKey(totWidth))
        {
          gaps.put(totWidth, gaps.get(totWidth) + 1);
        }
        else{
          gaps.put(totWidth, 1);
        }
      }
    }
 
    // Stores maximum number of 
    // gap from left
    int X = 0;
    for (Map.Entry Key : gaps.entrySet())
    {
      X = Math.max((int)Key.getValue(),X);
    }   
    System.out.print(tilesStack.size() - X);
  }
 
  // Driver code
  public static void main(String[] args)
  {
    Vector> tilesStack = new Vector>();
    tilesStack.add(new Vector());
    tilesStack.get(0).add(2);
    tilesStack.get(0).add(3);
    tilesStack.add(new Vector());
    tilesStack.get(1).add(3);
    tilesStack.get(1).add(2);
    tilesStack.add(new Vector());
    tilesStack.get(2).add(1);
    tilesStack.get(2).add(1);
    tilesStack.get(2).add(1);
    tilesStack.get(2).add(2);
    tilesStack.add(new Vector());
    tilesStack.get(3).add(1);
    tilesStack.get(3).add(1);
    tilesStack.get(3).add(1);
    tilesStack.get(3).add(1);
    tilesStack.get(3).add(1);
 
    // Function Call
    cutTiles(tilesStack);
  }
}
 
// This code is contributed by divyeshrabadiya07.


Python
# Python3 program for the above approach
 
# Function to count the minimum number
# of tiles that gets cut by a single
# vertical strike of a sword
def cutTiles(tilesStack):
     
     
    # Map prefix sum of each row
    # of tilesStack
    gaps = {}
 
    # Handling the case when
    # map will be empty
    gaps[-1] = 0
 
    # Traverse each row of the tiles
    for tiles in tilesStack:
 
        # Stores distance of gap from
        # left of each row
        totWidth = 0
 
        # Excluding the last gap as it will
        # be the edge of the level
        for tile in tiles[:-1]:
 
            # Update totWidth
            totWidth += tile
 
 
            # If gap is already found at
            # this points in previous levels
            if totWidth in gaps:
                gaps[totWidth] += 1
            else:
                gaps[totWidth] = 1
 
 
    # Stores maximum number of
    # gap from left
    X = max(list(gaps.values()))
     
    print(len(tilesStack) - X)
 
 
# Driver Code
if __name__ == '__main__':
     
    tilesStack = [[2, 3], [3, 2], [1, 1, 1, 2],
                              [1, 1, 1, 1, 1]]
 
    # Function Call
    cutTiles(tilesStack)


C#
// C# program for the above approach
using System;
using System.Collections.Generic;
class GFG {
     
    // Function to count the minimum number
    // of tiles that gets cut by a single
    // vertical strike of a sword
    static void cutTiles(List> tilesStack)
    {
        // Map prefix sum of each row
        // of tilesStack
        Dictionary gaps = new Dictionary();
       
        // Traverse each row of the tiles
        foreach(List tiles in tilesStack)
        {
            // Stores distance of gap from
            // left of each row
            int totWidth = 0;
       
            // Excluding the last gap as it will
            // be the edge of the level
            for(int i = 0; i < tiles.Count - 1; i++)
            {
                // Update totWidth
                totWidth += tiles[i];
                 
                // If gap is already found at
                // this points in previous levels
                if(gaps.ContainsKey(totWidth))
                {
                    gaps[totWidth] += 1;
                }
                else{
                    gaps[totWidth] = 1;
                }
            }
        }
       
        // Stores maximum number of 
        // gap from left
        int X = 0;
        foreach(KeyValuePair Key in gaps)
        {
            X = Math.Max(Key.Value,X);
        }
           
        Console.WriteLine(tilesStack.Count - X);
    }
     
  static void Main() {
    List> tilesStack = new List>();
    tilesStack.Add(new List());
    tilesStack[0].Add(2);
    tilesStack[0].Add(3);
    tilesStack.Add(new List());
    tilesStack[1].Add(3);
    tilesStack[1].Add(2);
    tilesStack.Add(new List());
    tilesStack[2].Add(1);
    tilesStack[2].Add(1);
    tilesStack[2].Add(1);
    tilesStack[2].Add(2);
    tilesStack.Add(new List());
    tilesStack[3].Add(1);
    tilesStack[3].Add(1);
    tilesStack[3].Add(1);
    tilesStack[3].Add(1);
    tilesStack[3].Add(1);
   
    // Function Call
    cutTiles(tilesStack);
  }
}
 
// This code is contributed by divyeshrbadiya07.


输出:
1

时间复杂度: O(N * M),其中 N 是级别的总数,M 是每个级别的宽度
辅助空间: O(M)