2060. 奶牛选美
听说最近两斑点的奶牛最受欢迎,约翰立即购进了一批两斑点牛。
不幸的是,时尚潮流往往变化很快,当前最受欢迎的牛变成了一斑点牛。
约翰希望通过给每头奶牛涂色,使得它们身上的两个斑点能够合为一个斑点,让它们能够更加时尚。
牛皮可用一个 N×MN×M 的字符矩阵来表示,如下所示:
................
..XXXX....XXX...
...XXXX....XX...
.XXXX......XXX..
........XXXXX...
.........XXX....
其中,XX 表示斑点部分。
如果两个 XX 在垂直或水平方向上相邻(对角相邻不算在内),则它们属于同一个斑点,由此看出上图中恰好有两个斑点。
约翰牛群里所有的牛都有两个斑点。
约翰希望通过使用油漆给奶牛尽可能少的区域内涂色,将两个斑点合为一个。
在上面的例子中,他只需要给三个 .. 区域内涂色即可(新涂色区域用 ∗∗ 表示):
................
..XXXX....XXX...
...XXXX*...XX...
.XXXX..**..XXX..
........XXXXX...
.........XXX....
请帮助约翰确定,为了使两个斑点合为一个,他需要涂色区域的最少数量。
输入格式
第一行包含两个整数 NN 和 MM。
接下来 NN 行,每行包含一个长度为 MM 的由 XX 和 .. 构成的字符串,用来表示描述牛皮图案的字符矩阵。
输出格式
输出需要涂色区域的最少数量。
数据范围
1≤N,M≤501≤N,M≤50
输入样例:
6 16
................
..XXXX....XXX...
...XXXX....XX...
.XXXX......XXX..
........XXXXX...
.........XXX....
输出样例:
3
pair是将2个数据组合成一组数据,当有这样的需求时,就可以用pair,另一个应用就是函数需要返回2个数据时,可以选择pair,pair得实现是一个结构体,主要成员变量是first,second,可以直接使用pair的成员变量
将两个斑点分别存进v【0】,v【1】两个动态数组里面,两点之间最短的距离就是|x1-x2|+|y1-y2|-1,取最短距离就行
#include<iostream>
#include<algorithm>
#include<vector>
#include<cstring>
#define x first//pair成员变量的引用
#define y second//pair成员变量的引用
using namespace std;
const int N=55;
typedef pair<int,int>pii;//pair定义
int n,m;
vector<pii>v[2];//装载两个图的坐标
char g[N][N];
int dx[4]={-1,0,1,0},dy[4]={0,1,0,-1};
void dfs(int i,int j,vector<pii>&v){//深度
g[i][j]='.';
v.push_back({i,j});
for(int k=0;k<4;k++){
int x=i+dx[k],y=j+dy[k];
if(x>=0&&x<n&&y>=0&&y<m&&g[x][y]=='X'){
dfs(x,y,v);
}
}
}
int main(){
cin>>n>>m;
for(int i=0;i<n;i++)cin>>g[i];
for(int i=0,k=0;i<n;i++){
for(int j=0;j<m;j++){
if(g[i][j]=='X')
dfs(i,j,v[k++]);
}
}
int ans=1e8;
for(auto& a:v[0]){
for(auto& b:v[1]){
ans=min(ans,abs(a.x-b.x)+abs(a.y-b.y)-1);
}
}
cout<<ans;
return 0;
}