hdoj1198
题目链接
这题思路非常简单,就是运用dfs判断有几个子图的问题,只不过预处理比较麻烦,我采用一个数组dir来保存各种管道的形状与周围区域的连接情况。但是我因为输入时搞混了n和m的位置而WA~~了好多次,看来得看清题目啊,最简单的地方都不能忽视,不然大把时间浪费了;
#include <iostream>
#include <cstring>
#include <fstream>
#include <algorithm>
#include <cstdio>
#include <string>
using namespace std;
int map[55][55];
bool vis[55][55];
int n, m;
const int dir[11][4] = {{0, 1, 0, 1}, {1, 0, 0, 1}, {0, 1, 1, 0}, {1, 0, 1, 0},
{0, 0, 1, 1}, {1, 1, 0, 0}, {1, 1, 0, 1}, {0, 1, 1, 1},
{1, 1, 1, 0}, {1, 0, 1, 1}, {1, 1, 1, 1}}; // 东西南北
const int go[4][2] = {0, 1, 0, -1, 1, 0, -1, 0}; //东西南北
bool inArea(int x, int y) {
return (x <= m && x > 0 && y <= n && y > 0);
}
void dfs(int i, int j) {
vis[i][j] = true;
for(int k = 0; k < 4; ++ k) {
if(!dir[map[i][j]][k] == 1) {
continue;
}
int a = i + go[k][0];
int b = j + go[k][1];
if(inArea(a, b) && !vis[a][b]) { 判断相邻两块区域是否联通
int loc = map[a][b];
if(k == 0 && dir[loc][1] == 1) {
dfs(a, b);
}
else if(k == 1 && dir[loc][0]) {
dfs(a, b);
}
else if(k == 2 && dir[loc][3]) {
dfs(a, b);
}
else if(k == 3 && dir[loc][2]) {
dfs(a, b);
}
}
}
}
int main() {
//ifstream cin("data.in");
while( cin >> m >> n && n > 0 && m > 0) { //warning:变量位置错误
memset(vis, false, sizeof(vis));
for(int i = 0; i < m; ++ i) {
string s;
cin >> s;
for(int j = 0; j < n; ++ j) {
map[i+1][j+1] = s.at(j) - 'A';
}
}
int cnt = 0;
for(int i = 1; i <= m; i ++) {
for(int j = 1; j <= n; ++ j) {//统计联通子图个数
if(!vis[i][j]) {
cnt ++;
dfs(i, j);
}
}
}
cout << cnt << endl;
}
return 0;
}