# 130.小美的字符串变换 本题是[岛屿数量](./0099.岛屿的数量广搜.md)的进阶版,主要思路和代码都是一样的,统计一个图里岛屿的数量,也是染色问题。 1、 先枚举各个可能出现的矩阵 2、 针对矩阵经行广搜染色(深搜,并查集一样可以) 3、 统计岛屿数量最小的数量。 ```CPP #include #include #include #include using namespace std; // 广搜代码同 卡码网:99. 岛屿数量 int dir[4][2] = {0, 1, 1, 0, -1, 0, 0, -1}; // 四个方向 void bfs(const vector>& grid, vector>& visited, int x, int y, char a) { queue> que; que.push({x, y}); visited[x][y] = true; // 只要加入队列,立刻标记 while(!que.empty()) { pair cur = que.front(); que.pop(); int curx = cur.first; int cury = cur.second; for (int i = 0; i < 4; i++) { int nextx = curx + dir[i][0]; int nexty = cury + dir[i][1]; if (nextx < 0 || nextx >= grid.size() || nexty < 0 || nexty >= grid[0].size()) continue; // 越界了,直接跳过 if (!visited[nextx][nexty] && grid[nextx][nexty] == a) { que.push({nextx, nexty}); visited[nextx][nexty] = true; // 只要加入队列立刻标记 } } } } int main() { int n; string s; cin >> n; int result = INT_MAX; cin >> s; for (int k = 1; k < n; k++) { if (n % k != 0) continue; // 计算出 矩阵的 行 和 列 int x = n / k; int y = k; //cout << x << " " << y << endl; vector> vec(x, vector(y, 0)); // 填装矩阵 int sCount = 0; for (int i = 0; i < x; i++) { for (int j = 0; j < y; j++) { vec[i][j] = s[sCount++]; } } // 开始广搜染色 vector> visited(x, vector(y, false)); int count = 0; for (int i = 0; i < x; i++) { for (int j = 0; j < y; j++) { if (!visited[i][j]) { count++; // 遇到没访问过的陆地,+1 bfs(vec, visited, i, j, vec[i][j]); // 将与其链接的陆地都标记上 true } } } // 取岛屿数量最少的 result = min (result, count); } cout << result << endl; } ```