这个题目因为数据范围比较小,貌似可以用多种算法求解,本人目前暂时使用最大二分图匹配,使用的是行和列匹配。。。。。水平不高,开的数组比较多,mapr表示对地图的行进行编号,每行中被X隔开的地方编号,同理将列也如是编好序号,这样都编号完毕后开始组建二分图,以行和列的编号作为二分图的X,Y集合,然后计算最大二分匹配即可。
例如:
4
.X..
....
XX..
....
则行标号结果为:
4
1 -1 2 2
2 2 2 2
-1 -1 33
4 4 4 4
同理得列编号。。。然后二分匹配。
代码如下:
# include <iostream>
using namespace std;
int n;
const int Go[4][2] = {{0, 1}, {0, -1}, {-1, 0}, {1, 0}};
char map[4][4];
int mapr[4][4];
int mapl[4][4];
int mape[20][20];
int flag[20], mark[20];
int rr=0, ll=0;
int dfs(int x)
{
for (int i = 1; i <= ll; i ++){
if (!(mape[x][i]) || flag[i]){
continue;
}
flag[i] = 1;
if (!mark[i]|| dfs(mark[i])){
mark[i] = x;
return 1;
}
}
return 0;
}
int main()
{
while (scanf("%d", &n) != EOF && n){
memset(mapl, 0, sizeof(mapl));
memset(mapr, 0, sizeof(mapr));
memset(mape, 0, sizeof(mape));
memset(mark, 0, sizeof(mark));
for (int i = 1; i <= n; i ++){getchar();
for (int j = 1; j <= n; j ++){
scanf("%c", &map[i][j]);
if (map[i][j] == 'X'){
mapl[i][j] = mapr[i][j] = -1;
}
}
}
int p1 = 0;
int check1 = 0;
rr =0, ll = 0;
for (int i = 1; i <= n; i ++){
for (int j = 1; j <= n; j ++){
while (mapr[i][j] == -1&&j<=n){
j ++;
}
p1 ++;
while (mapr[i][j] != -1&&j<=n){
mapr[i][j] = p1;
if (rr < p1)rr = p1;
j ++;
}
}
}
int p2 = 0;
for (int i = 1; i <= n; i ++){
for (int j = 1; j <= n; j ++){
while (mapl[j][i] == -1&&j<=n){
j ++;
}
p2 ++;
while (mapl[j][i] != -1&&j<=n){
mapl[j][i] = p2;
if (ll < p2)ll = p2;
j ++;
}
}
}
for (int i = 1; i <= n; i ++){
for (int j = 1; j <= n; j ++){
if (mapr[i][j]!=-1&&mapl[i][j] != -1){
mape[mapr[i][j]][mapl[i][j]] = 1;
}
}
}
int counter = 0;
memset(mark, 0, sizeof(mark));
for (int i = 1; i <= rr; i ++){
memset(flag, 0, sizeof(flag));
if (dfs(i)){
counter ++;
}
}
printf("%d/n", counter);
}
return 0;
}