CF_2069_B. Set of Strangers
题目链接:Problem - B - Codeforces
题目大意:
给定一个 的矩阵, 表示第 行第 列方格的颜色。
所有颜色相同且不相邻的方格称为陌生的集合。
每次操作可以将一个陌生的集合变成其他的颜色。
求将整个矩阵都变成同一颜色的最小操作次数。
思路:
把矩阵中的一个颜色变成另一个颜色,最多只需要两次
证明:
对于每个方格,与他相同颜色的方格可以分为两部分,即相邻的与不相邻的,
对于不相邻的只需要一次操作就可以把 自己和不相邻的 变成其他颜色,
对于相邻的,以相邻的块为当前块,再进行上面的一次操作,这样这种颜色就全部换掉
代码:
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<vector>
#include<queue>
#include<deque>
#include<stack>
#include<set>
#include<map>
#include<unordered_set>
#include<unordered_map>
#include<bitset>
#include<tuple>
#define inf 72340172838076673
#define int long long
#define endl '\n'
#define F first
#define S second
#define mst(a,x) memset(a,x,sizeof (a))
using namespace std;
typedef pair<int, int> pii;
const int N = 200086, mod = 998244353;
int n, m;
int res = 0;
void solve() {
cin >> n >> m;
vector<vector<int>> e(n + 2, vector<int>(m + 2));
vector<int> v(n * m + 2), bad(n * m + 2);
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
cin >> e[i][j];
}
}
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
int x = e[i][j];
v[x] = 1;
if (i < n && e[i][j] == e[i + 1][j]) bad[x] = 1;
if (j < m && e[i][j] == e[i][j + 1]) bad[x] = 1;
}
}
int c = 0, b = 0, mx = 0;
for (int i = 1; i <= n * m; i++) {
c += v[i];
b += bad[i];
mx = max(mx, bad[i]);
}
res = c + b - 1 - mx;
cout << res << endl;
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(nullptr), cout.tie(nullptr);
int T = 1;
cin >> T;
while (T--) solve();
return 0;
}

浙公网安备 33010602011771号