700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > 2060. 奶牛选美

2060. 奶牛选美

时间:2021-07-02 06:22:58

相关推荐

2060. 奶牛选美

作者 : Xia Xinyu

日期 : -1-3

原题链接

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

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

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

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

…XXXX…XXX…

…XXXX…XX…

.XXXX…XXX…

…XXXXX…

…XXX…

其中,X 表示斑点部分。

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

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

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

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

…XXXX…XXX…

…XXXX*…XX…

.XXXX…**…XXX…

…XXXXX…

…XXX…

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

输入格式

第一行包含两个整数 N 和 M。

接下来 N 行,每行包含一个长度为 M 的由 X 和 . 构成的字符串,用来表示描述牛皮图案的字符矩阵。

输出格式

输出需要涂色区域的最少数量。

数据范围

1≤N,M≤50

输入样例:

6 16

…XXXX…XXX…

…XXXX…XX…

.XXXX…XXX…

…XXXXX…

…XXX…

输出样例:

3

思路:推导出最优解一定可以用曼哈顿距离公式求出(反证法)

import java.util.*;class Main{static int[] dx = {1,0,-1,0}; //下右上左static int[] dy = {0,1,0,-1};static char[][] g = new char[60][60];static int n,m;public static void dfs(int x,int y,List<Pair> l){g[x][y] = '.';for(int i = 0; i < 4; i ++){int aa = x + dx[i],bb = y + dy[i];if(aa >= 0 && aa < n && bb >= 0 && bb < m && g[aa][bb] == 'X'){l.add(new Pair(aa,bb));dfs(aa,bb,l);}}}public static void main(String[] args){Scanner in = new Scanner(System.in);n = in.nextInt();m = in.nextInt();for(int i = 0; i < n; i ++){g[i] = in.next().toCharArray();}List<Pair> a = new ArrayList<>();List<Pair> b = new ArrayList<>();boolean flag = false;//搜第一个连通块for(int i = 0; i < n; i ++){for(int j = 0; j < m; j ++){if(g[i][j] == 'X'){a.add(new Pair(i,j));dfs(i,j,a);flag = true;break;}}if(flag)break;}//搜第二个连通块for(int i = 0; i < n; i ++){for(int j = 0; j < m; j ++){if(g[i][j] == 'X'){b.add(new Pair(i,j));dfs(i,j,b);}}}// System.out.println(a.size());// System.out.println(b.size());int res = (int)2e9;for(Pair x : a){for(Pair y : b){res = Math.min(res,Math.abs(x.x - y.x) + Math.abs(x.y - y.y));}}System.out.println(res - 1);}}class Pair {int x;int y;public Pair(int x,int y){this.x = x;this.y = y;}}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。
扩展阅读