笔试题.放置货物(java):单调栈

题目来源
在这里插入图片描述
示例
在这里插入图片描述
思路
和leetcode85题有异曲同工之妙。
可以理解成放置了障碍物的格子相当于‘0’,空闲格子相当于‘1’
1.首先用boolean[][] square记录广场上放置障碍物的情况。有障碍物的格子设为true(因为boolean初始值为false)。
2.根据square,画柱形图

for(int i = 0;i < square.length;i++){
   for(int j = 0;j < square[0].length;j++){
       if(!square[i][j]){
           dp[j]++;
       }else{
           dp[j] = 0;
       }
  }
}

3.使用单调栈,以栈顶元素为高,判断高是否>=物品行宽c,再判断宽是否>=物品列宽d
若满足条件,则输出“YES”,否则继续遍历,若遍历完后没有符合条件的位置,输出"NO"

具体代码

import java.util.Scanner;
import java.util.Stack;
public class Main{
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        int size = sc.nextInt();
        while(size > 0){
            int n = sc.nextInt();
            int m = sc.nextInt();
            int k = sc.nextInt();
            boolean square[][] = new boolean[n][m];
            for(int i = 0;i < k;i++){
                square[sc.nextInt()-1][sc.nextInt()-1] = true;
            }
            int c = sc.nextInt();
            int d = sc.nextInt();
            if(zhuxingtu(square,c,d)){
                System.out.println("YES");
            }else{
                System.out.println("NO");
            }
            //这里一定要记住--
            size--;
        }
    }
    public static boolean zhuxingtu(boolean[][]square,int c,int d){
        //构建柱形图
            int dp[] = new int[square[0].length];
            for(int i = 0;i < square.length;i++){
                for(int j = 0;j < square[0].length;j++){
                    if(!square[i][j]){
                        dp[j]++;
                    }else{
                        dp[j] = 0;
                    }
                }
                if(canPlace(dp,c,d)){
                    return true;
                }
            }
        return false;
    }
    public static boolean canPlace(int height[],int c,int d){
    //这里要记住栈内存的是高所在的索引位置
    Stack<Integer> stack = new Stack<>();
    stack.push(-1);
    for(int i = 0;i < height.length;i++){
        while(stack.peek()!=-1 && height[i]<height[stack.peek()]){
            if(height[stack.pop()]>=c && (i-stack.peek()-1>=d)){
                //System.out.println("YES");
                return true;
            }
        }
        stack.push(i);
    }
    while(stack.peek()!=-1){
        if(height[stack.pop()]>=c && (height.length-stack.peek()-1>=d)){
                //System.out.println("YES");
                return true;
            }
    }
     //System.out.println("NO");
    return false;
    }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值