3888:奶牛选美大赛(dfs+曼哈顿距离)
作者:互联网
描述
听说最新的时尚趋势是母牛的皮上有两个斑点,农夫约翰购买了一整群有两个斑点的奶牛。不幸的是,时尚潮流往往瞬息万变,而当下最流行的时尚是只有一个位置的奶牛!
FJ 想通过将他的每头奶牛画成将它们的两个斑点合二为一的方式来使他的牛群更时尚。母牛的皮由 N x M (1 <= N,M <= 50) 字符网格表示,如下所示:
......
..XXXX....XXX...
...XXXX....XX...
.XXXX......XXX..
........XXXXX
............XXX....
这里,每个“X”表示一个点的一部分。两个'X'如果垂直或水平相邻(对角相邻不算)属于同一个点,所以上图正好有两个点。FJ 牛群中的所有奶牛正好有两个斑点。
FJ 想用尽可能少的颜料将两个点合并为一个。在上面的例子中,他可以通过只用'X'画三个额外的字符来做到这一点(新字符在下面用'*'标记以便更容易看到)。
......
..XXXX..XXX...
...XXXX*...XX...
.XXXX..**..XXX..
........XXXXX
............XXX....
请帮助 FJ 确定他必须绘制的最小新“X”数量,以便将两个点合并为一个大点。
输入
* 第 1 行:两个空格分隔的整数,N 和 M。
* 第 2..1+N 行:每行包含一个长度为 M 的字符串,由 'X' 和 '.' 组成,指定一行牛皮图案。
输出
* 第 1 行:为获得一个点,必须添加到输入模式中的新“X”的最小数量。
样例输入
6 16
................
..XXXX....XXX...
...XXXX....XX...
.XXXX......XXX..
........XXXXX...
.........XXX....
样例输出
3
AC:输入完扫一遍地图,遇到X就搜一遍全部标记上,并且把搜到的X的坐标都添加到vector中,这样扫一遍地图就可以得到两块X的所有点坐标,然后比较两块X所有点的坐标求曼哈顿距离计算出最小值
#include<bits/stdc++.h> using namespace std; char a[55][55]; int nex[4][2] = {{0,1},{1,0},{0,-1},{-1,0}}; vector<int>xp[3];//二维向量 vector<int>yp[3]; int n,m,book[55][55]; void dfs(int x,int y,int t) { int tx,ty; for(int i=0;i<4;i++) { tx = nex[i][0]+x; ty = nex[i][1]+y; if(tx<1||ty<1||tx>n||ty>m)continue; if(a[tx][ty]=='X'&&book[tx][ty]==0){ book[tx][ty] = 1; xp[t].push_back(tx); yp[t].push_back(ty); a[tx][ty] = '.'; dfs(tx,ty,t); } } } int main(){ cin>>n>>m; for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) { cin>>a[i][j]; } } int l=1; for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) { if(a[i][j]=='X'&&book[i][j]==0) { book[i][j] = 1; xp[l].push_back(i); yp[l].push_back(j); dfs(i,j,l); l++; } } } int minn = 2500; int px1,py1,px2,py2; for(int i=0;i<xp[1].size();i++) { for(int j=0;j<xp[2].size();j++) { px1 = xp[1][i]; py1 = yp[1][i]; px2 = xp[2][j]; py2 = yp[2][j]; minn = min(abs(px1-px2)+abs(py1-py2)-1,minn);//求曼哈顿距离=绝对值(x)+绝对值(y) } } cout<<minn<<endl; return 0; }
标签:XXXX,tx,ty,int,XXX,....,3888,dfs,选美 来源: https://www.cnblogs.com/jyssh/p/16609958.html