题意 给你一个城市的地图 你可以在地图上的 . 上建房子#上不能建房子 红房子可以装200个人 蓝房子可以装100个人 只有相邻位置有蓝房子时才能建红房子 你也可以拆掉已经建成的房子 拆掉后该点又变成 .
这题想到了就很容易了 因为没有限制要步数最少 可以先把左右的地方都建成蓝房子 然后就变成求连通块的题了 每个蓝房子连通块内依次拆掉建红房子 最终就只剩下一个蓝房子了
#include <bits/stdc++.h>
using namespace std;
const int N = 505;
char g[N][N];
stack<pair<int, int> > s;
int x[] = { -1, 1, 0, 0};
int y[] = {0, 0, -1, 1};
int n, m, a, b, cnt, is_first;
int dfs(int i, int j)
{
int r, c;
if(is_first) is_first = 0;
else s.push(make_pair(i, j));
g[i][j] = 'R', cnt += 3;
for(int k = 0; k < 4; ++k)
{
r = i + x[k], c = j + y[k];
if(g[r][c] == '.') dfs(r, c);
}
}
int main()
{
while(~scanf("%d%d", &n, &m))
{
cnt = 0;
for(int i = 1; i <= n; ++i)
scanf("%s", g[i] + 1);
for(int i = 1; i <= n; ++i)
for(int j = 1; j <= m; ++j)
if(g[i][j] == '.') is_first = 1, cnt -= 2, dfs(i, j);
printf("%d\n", cnt);
for(int i = 1; i <= n; ++i)
for(int j = 1; j <= m; ++j)
if(g[i][j] != '#') printf("B %d %d\n", i, j);
while(!s.empty())
{
a = s.top().first, b = s.top().second;
printf("D %d %d\nR %d %d\n", a, b, a, b);
s.pop();
}
}
return 0;
}