标签:
定义一段无法向左右扩展的连续非障碍物方格为行连通块,一段无法向上下扩展的连续非障碍物方格为列连通块 我们把行连通块对应X集合,列连通块对应Y集合,如果一个行连通块与一个列连通块有交点且为空地,则对应在二分图中有一条边 显然房子的集合对应二分图的一个匹配,任意两个房子不可能共同存在于一个行或列连通块中,所以最多房子数目=最大匹配数 #include<stdio.h> #include<string.h> #include<algorithm> #define N 10 using namespace std; char Map[N][N]; int G[N][N]; int use[N], vis[N]; int n, rn, cn; int Find(int u) { int i; for (i = 1; i <= cn; i++) { if (!vis[i] && G[u][i]) { vis[i] = 1; if (!use[i] || Find(use[i])) { use[i] = u; return 1; } } } return 0; } int main () { int i, j, r, c, ans; int mapr[N][N], mapc[N][N]; while (scanf("%d", &n), n) { r = c = rn = cn = ans = 0; memset(G, 0, sizeof(G)); memset(use, 0, sizeof(use)); memset(mapr, 0, sizeof(mapr)); memset(mapc, 0, sizeof(mapc)); for (i = 0; i < n; i++) scanf("%s", Map[i]); for (i = 0; i < n; i++) for (j = 0; j < n; j++) if (Map[i][j] == ‘X‘) mapr[i][j] = mapc[i][j] = -1; for (i = 0; i < n; i++) { for (j = 0; j < n; j++) { while (mapr[i][j] == -1 && j < n) j++; r++; while (mapr[i][j] != -1 && j < n) { mapr[i][j] = r; //建立行连通块 if (rn < r) rn = r; j++; } } } for (j = 0; j < n; j++) { for (i = 0; i < n; i++) { while (mapc[i][j] == -1 && i < n) i++; c++; while (mapc[i][j] != -1 && i < n) { mapc[i][j] = c; //建立列连通块 if (cn < c) cn = c; i++; } } } for (i = 0; i < n; i++) for (j = 0; j < n; j++) if (mapr[i][j] != -1 && mapc[i][j] != -1) G[mapr[i][j]][mapc[i][j]] = 1; //重新构图 for (i = 1; i <= rn; i++) { memset(vis, 0, sizeof(vis)); if (Find(i)) ans++; } printf("%d\n", ans); } return 0; }
2.该题还可以暴力搜索:
#include<stdio.h> #include<algorithm> #define N 10 using namespace std; char Map[N][N]; int n, Max; int Judge(int x, int y) //判断该行该列是否已经建过房子或者有障碍物 { int i; for (i = x-1; i >= 0; i--) { if (Map[i][y] == ‘#‘) //建过房子,则不能再建 return 0; if (Map[i][y] == ‘X‘) //有障碍物,则还能再建 break; } for (i = y-1; i >= 0; i--) { if (Map[x][i] == ‘#‘) return 0; if (Map[x][i] == ‘X‘) break; } return 1; } void DFS(int s, int c) //s表示走的步数,c表示可以建几座房子 { int x, y; Max = max(Max, c); if (s == n*n) return ; x = s / n; //x表示行 y = s % n; //y表示列 if (Map[x][y] == ‘.‘ && Judge(x, y)) { Map[x][y] = ‘#‘; DFS(s+1, c+1); //如果这点可以建立房子,则步数增加,房子总数增加 Map[x][y] = ‘.‘; } DFS(s+1, c); //即使这个点不能建房子,步数依然要增加 } int main () { int i; while (scanf("%d", &n), n) { for (i = 0; i < n; i++) scanf("%s", Map[i]); Max = 0; DFS(0, 0); printf("%d\n", Max); } return 0; }
标签:
原文地址:http://www.cnblogs.com/syhandll/p/4718734.html