奶牛选美


题目链接:

2060. 奶牛选美 - AcWing题库

听说最近两斑点的奶牛最受欢迎,约翰立即购进了一批两斑点牛。

不幸的是,时尚潮流往往变化很快,当前最受欢迎的牛变成了一斑点牛。

约翰希望通过给每头奶牛涂色,使得它们身上的两个斑点能够合为一个斑点,让它们能够更加时尚。

牛皮可用一个 N×M 的字符矩阵来表示,如下所示:

................
..XXXX....XXX...
...XXXX....XX...
.XXXX......XXX..
........XXXXX...
.........XXX....

其中,X 表示斑点部分。

如果两个 X 在垂直或水平方向上相邻(对角相邻不算在内),则它们属于同一个斑点,由此看出上图中恰好有两个斑点。

约翰牛群里所有的牛都有两个斑点

约翰希望通过使用油漆给奶牛尽可能少的区域内涂色,将两个斑点合为一个。

在上面的例子中,他只需要给三个 .. 区域内涂色即可(新涂色区域用 ∗ 表示):

................
..XXXX....XXX...
...XXXX*...XX...
.XXXX..**..XXX..
........XXXXX...
.........XXX....

请帮助约翰确定,为了使两个斑点合为一个,他需要涂色区域的最少数量。

代码:

import java.util.*;


public class Main {
    static int n, m;
    static int N = 100;
    static int[] xx = {1,0,-1,0};
    static int[] yy = {0,1,0,-1};
    static char[][] s = new char[N][N];
    static boolean[][] f = new boolean[N][N];
    static List<node>[] q = new ArrayList[2];

    static class node{
        int x, y;
        public node(int x, int y) {
            this.x = x;
            this.y = y;
        }
    }
    public static void bfs(int x, int y, int cnt) {
        f[x][y] = true;
        q[cnt].add(new node(x, y));
        for(int i = 0; i < 4; i ++)
        {
            int x1 = x + xx[i];
            int y1 = y + yy[i];
            if(0 <= x1 && x1 < n && 0 <= y1 && y1 < m && !f[x1][y1] && s[x1][y1] == 'X')
                bfs(x1, y1, cnt);
        }
    }
    public static void main(String[] args) {
        Scanner inScanner = new Scanner(System.in);
        n = inScanner.nextInt();
        m = inScanner.nextInt();
        for(int i = 0; i < q.length; i ++)
            q[i] = new ArrayList<>();
        for(int i = 0; i < n; i ++)
        {
            String ss;
            ss = inScanner.next();
            for(int j = 0; j < m; j ++)
                s[i][j] = ss.charAt(j);
        }
        int cnt = 0;
        for(int i = 0; i < n; i ++)
        {
            for(int j = 0; j < m; j ++)
            {
                if(!f[i][j] && s[i][j] == 'X')
                {
                    bfs(i, j, cnt);
                    cnt ++;
                }
            }
        }
        inScanner.close();
        int ans = 100000;
        for(node a : q[0])
            for(node b : q[1])
            {
                int t = Math.abs(a.x - b.x) + Math.abs(a.y - b.y) - 1;
                ans = Math.min(ans, t);
            }
        System.out.println(ans);
    }
}
/*
 * 
6 16
................
..XXXX....XXX...
...XXXX....XX...
.XXXX......XXX..
........XXXXX...
.........XXX....
 **/

文章作者: 姜小白
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 姜小白 !
评论
  目录