【宽度优先】水域污染

本文介绍了一个Java程序,用于模拟水域污染扩散过程,给定一个N*N的数组表示水域状态,计算在每一步污染邻近格子的情况下,使所有水域污染所需的最少天数。如果无法全部污染,则返回-1。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

import java.io.*;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.Queue;

/**
 * 水域污染
 * 我们需要输入一个字符串,它代表着一个N*N的数组,该数组表示水域。你需要做的是需要判断多少天后水域将被全部污染
 * 数组的限制条件:数组中只包含0和1,其中0表示纯净的水域,1表示已经污染的水域。每个格子每天只能污染上下左右相邻的水域
 * 如果水域无法被完全污染,则返回-1
 * 例如示例输入
 * 1,0,1,0,0,0,1,0,1
 * 将其转化为数组
 * 1 0 1
 * 0 0 0
 * 1 0 1
 * 第一天后,水域变为
 * 1 1 1
 * 1 0 1
 * 1 1 1
 * 第二天,水域被全部污染
 * 输出2
 */
public class WaterPollution {
    /**
     * 向右、向下、向左、向上
     */
    private static final int[][] DIRECTIONS = { {0, 1}, {1, 0}, {0, -1}, {-1, 0} };

    /*
        1,0,1,0,0,0,1,0,1
        ------------------------
        2
     */
    private static String line;
    private static String[] strArr;
    private static int[] nums;
    private static int length;
    private static int dimension;
    private static int[][] grid;

    public static void main(String[] args) throws IOException {
        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
        PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
        line = in.readLine();
        strArr = line.split(",");
        length = strArr.length;
        dimension = (int) Math.sqrt(length);
        grid = new int[dimension][dimension];
        nums = Arrays.stream(strArr).mapToInt(Integer::parseInt).toArray();
        out.println(waterPollution());
        out.flush();
        in.close();
        out.close();
    }

    public static int waterPollution() {
        //清水数量
        int cleanWaterCount = 0;
        //污染天数
        int days = 0;
        //污染队列
        Queue<int[]> pollutedQueue = new LinkedList<>();
        for (int i = 0; i < length; i++) {
            int x = i / dimension;
            int y = i % dimension;
            grid[x][y] = nums[i];
            //污水格子加入队列
            if (grid[x][y] == 1) {
                pollutedQueue.add(new int[]{x, y});
            } else {
                cleanWaterCount++;
            }
        }
        //污水队列为空或清水归零时跳出循环
        while (!pollutedQueue.isEmpty() && cleanWaterCount > 0) {
            //获取当天的污水数量
            int size = pollutedQueue.size();
            //遍历污水格子
            for (int i = 0; i < size; i++) {
                //弹出栈顶污水格子
                int[] current = pollutedQueue.poll();
                if(current == null){
                    break;
                }
                //遍历四个方向
                for (int[] dir : DIRECTIONS) {
                    //确定新方向坐标
                    int newX = current[0] + dir[0];
                    int newY = current[1] + dir[1];
                    //新坐标不越界且恰好是纯净水,则污染一下
                    if (newX >= 0 && newX < dimension && newY >= 0 && newY < dimension && grid[newX][newY] == 0) {
                        grid[newX][newY] = 1;
                        //污水格子加入队列
                        pollutedQueue.offer(new int[]{newX, newY});
                        //纯净水自减
                        cleanWaterCount--;
                    }
                }
            }
            //当天的污染结束,则天数自增
            days++;
        }
        //全部污染,则返回天数,还有净水,则返回-1
        return cleanWaterCount == 0 ? days : -1;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值