算法题:放置货物

这是一道关于算法的编程题目,描述了如何在给定的n*m大小的广场中,避开k个障碍物成功放置一个占地为c*d的货物。通过输入的t组数据,判断每组情况下货物是否可以被放置,并输出'YES'或'NO'。

小易有一个体积巨大的货物,具体来说,是个在二维平面上占地cd的货物。
小易有一个n
m的广场,想把货物放在这个广场上。不幸的是,广场上已经有了一些障碍物,障碍物所在的格子不能放置你的货物。小易现在想知道能否成功地放置货物。

第一行数字t,表示有t组数据。
对于每一组数据,第一行三个数字n,m,k,表示广场的大小和障碍物的个数。接下来k行,每行两个数x,y,表示一个障碍物的坐标。
接下来一行两个数c,d,表示货物的大小。
1<=n,m<=1000,1<=c<=n,1<=d<=m,0<=k<=n*m

对于每组数据,输出"YES"或者"NO"表示货物是否可以被放置。

输入例子1:
2
3 3 1
1 1
2 2
3 3 1
2 2
2 2

输出例子1:
YES
NO

import java.util.Scanner;
public class main04 {
    public static void main(String[] args) {

        int t, c, d, n, m, k;

        Scanner scanner = new Scanner(System.in);
        System.out.println("输入:(1<=n,m<=1000,1<=c<=n,1<=d<=m,0<=k<=n*m)");
        System.out.println("输入有几组:");
        t = scanner.nextInt();
        boolean[] flags = new boolean[t];
        for (int i = 0; i < t; i++) {
            System.out.println("输入场地大小和障碍物数量:");
            n = scanner.nextInt();
            m = scanner.nextInt();
            k = scanner.nextInt();
            int[] k_x = new int[k];
            int[] k_y = new int[k];
            for (int j = 0; j < k; j++) {
                System.out.println("输入第"+(j+1)+"个障碍物位置:");
                k_x[j] = scanner.nextInt()-1;
                k_y[j] = scanner.nextInt()-1;
            }
            System.out.println("输入货物大小:");
            c = scanner.nextInt();
            d = scanner.nextInt();
            flags[i] = test(n,m,k,k_x,k_y,c,d);
        }
        for (int i = 0; i < t; i++) {
            System.out.print("第"+(i+1)+"组货物:");
            if (flags[i])
                System.out.println("YES");
            else
                System.out.println("NO");
        }
    }
    public static boolean test(int n,int m,int k,int[] k_x,int[] k_y,int c,int d){
        boolean flag = false;
        //最外层的两个循环,用来遍历每个可以安放货物的位置
        for (int i = 0; i < (n-c+1); i++) {
            for (int j = 0; j < (m-d+1); j++) {
                //每次判断前,将flag置为false,意味着该点范围内没有障碍物
                flag = false;
                //进行判定这个位置中的每个点是否有障碍物
                for (int l = 0; l < k; l++) {
                    //双if用来判断该位置是否是在这个范围内,如果存在,flag变为true
                    if (k_x[l]>=i&&k_x[l]<=(i+c-1)){
                        if (k_y[l]>=j&&k_y[l]<=(j+d-1)){
                            flag = true;
                        }
                    }
                }
                //当前面的循环判断结束后,若flag为true,说明有障碍物,则进行下一个点的判断
                //若循环结束,falg为false,说明该点范围内没有障碍物,则通过
                if (flag == false)
                        return true;
            }
        }

        //和前面代码相同,只是将货物变向放置,即障碍物长宽调换,但是要先判断
        if(n>=d&&m>=c){
            for (int i = 0; i < (n-d+1); i++) {
                for (int j = 0; j < (m-c+1); j++) {
                    flag = false;
                    for (int l = 0; l < k; l++) {
                        if (k_x[l]>=j&&k_x[l]<=(j+c-1)){
                            if (k_y[l]>=i&&k_y[l]<=(i+d-1)){
                                flag = true;
                            }
                        }
                    }
                    if (flag == false)
                        return true;
                }
            }
        }
        return false;
    }
}

(本方法并非最优算法)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值