/*
------------------------------------
画作
不难证明猜到一个这样的结论: 存在一种最优方案使得每次操作的区
域是上一次的子集且颜色与上一次相反.
考虑归纳证明, 记 S 为当前所有操作区域的并, T 为接下来一步的操作
区域, 我们有:
1. T 与 S 有交的情况一定可以转化成 T 被 S 包含的情况.
2. T 与 S 交集为空时, 可以找一个连接 S 和 T 的集合 M 并操作 S ∪
T ∪ M , 并将之前的所有操作连接到更外的层以及外层的连接部分同时
操作, 特殊处理最外层和第二层的情况.
3. T 被 S 包含时, T 落在某个完整区域内时等价于情况二, 否则一定连
接若干个同色块, 这些块可以同时处理, 步数一定不会更劣.
知道这个结论就比较好做了, 我们可以枚举最后被修改的区域, 这时答
案就是将同色边边权当作 0, 异色边边权当作 1 后距离这个点最远的黑色点
的距离, 对所有点取最小值即可.
r, c ≤ 50.
------------------------------------2018.10.5
其实这个结论是比较好想的,关键是怎么实现,这里有一个经典的方法:
同颜色边权为0,不同颜色边权为1,然后用deque跑bfs就可以了
考虑怎么理解这道题:
枚举最后被修改的区域,答案就是离它最远的黑色点的距离.
这个dis代表需要这么多步<产生只有一个黑块的状态,再加1步全部换成白色>
------------------------------------2018.11.5
*/
#include <bits/stdc++.h>
using std::pair;
using std::vector;
using std::string;
typedef long long ll;
typedef pair<int, int> pii;
#define fst first
#define snd second
#define pb(a) push_back(a)
#define mp(a, b) std::make_pair(a, b)
#define debug(...) fprintf(stderr, __VA_ARGS__)
template <typename T> bool chkmax(T& a, T b) { return a < b ? a = b, 1 : 0; }
template <typename T> bool chkmin(T& a, T b) { return a > b ? a = b, 1 : 0; }
const int oo = 0x3f3f3f3f;
string procStatus() {
std::ifstream t("/proc/self/status");
return string(std::istreambuf_iterator<char>(t), std::istreambuf_iterator<char>());
}
template <typename T> T read(T& x) {
int f = 1; x = 0;
char ch = getchar();
for(;!isdigit(ch); ch = getchar()) if(ch == '-') f = -1;
for(; isdigit(ch); ch = getchar()) x = x * 10 + ch - 48;
return x *= f;
}
const int N = 50;
int n, m;
char g[N + 5][N + 5];
int dis[N + 5][N + 5];
const int dx[] = { 1, 0, -1, 0 };
const int dy[] = { 0, 1, 0, -1 };
int bfs(int x, int y) {//最简单的广搜,边权0或1用双端队列deque
std::deque<pii> q;
memset(dis, -1, sizeof dis);
dis[x][y] = 0;
q.push_back(mp(x, y));
int res = 0;
while(!q.empty()) {
int cx = q.front().fst, cy = q.front().snd;
if(g[cx][cy] == '1')
chkmax(res, dis[cx][cy]);
q.pop_front();
for(int i = 0; i < 4; ++i) {
int nx = cx + dx[i], ny = cy + dy[i];
if(nx >= 0 && nx < n && ny >= 0 && ny < m && dis[nx][ny] == -1) {
if(g[nx][ny] == g[cx][cy]) {
dis[nx][ny] = dis[cx][cy];
q.push_front(mp(nx, ny));
} else {
dis[nx][ny] = dis[cx][cy] + 1;
q.push_back(mp(nx, ny));
}
}
}
}
return res;
}
int main() {
//freopen("paint.in", "r", stdin);
//freopen("paint.out", "w", stdout);
read(n), read(m);
for(int i = 0; i < n; ++i) {
scanf("%s", g[i]);
}
int ans = oo;
for(int i = 0; i < n; ++i) {
for(int j = 0; j < m; ++j) {
chkmin(ans, bfs(i, j));
}
}
printf("%d\n", ans + 1);
return 0;
}
原文地址:https://www.cnblogs.com/lizehon/p/10644762.html
时间: 2024-11-19 15:11:01