POJ 1414
找找手感一道题,有些类似于uva此前做过的一道判断照片字母形状的题,利用DFS求联通分量。
这里要格外注意边缘碰到0的情况的讨论,当遍历一个连通分量时,整个连通分量必须遍历完再推出,不可以分几次遍历同一连通分量,这是DEBUG好久得出的教训
#include <iostream>
#include <algorithm>
#include <queue>
#include <string>
#include <vector>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <string>
#include <stack>
#include <map>
#include <set>
#include <deque>
using namespace std;
const int maxn= 15;
const int INF= 0x3f3f3f3f;
int n, c;
int bd[maxn][maxn];
bool vis[maxn][maxn];
int step[6][2]= {
{-1, -1}, {-1, 0}, {0, -1}, {0, 1}, {1, 0}, {1, 1}
};
int dfs(int x, int y)
{
vis[x][y]= 1;
if (!bd[x][y]){
return 0;
}
int sm= 1;
int flag= 0;
for (int i= 0; i< 6; ++i){
int nx= x+step[i][0], ny= y+step[i][1];
if (!bd[nx][ny]){
flag= 1;
}
if (bd[x][y]!= bd[nx][ny]){
continue;
}
else if (!vis[nx][ny]){
int tp= dfs(nx, ny);
if (!tp){
flag= 1;
}
sm+= tp;
}
}
return flag ? 0 : sm;
}
int main(int argc, char const *argv[])
{
memset(bd, -1, sizeof(bd));
while (2== scanf("%d %d", &n, &c) && n){
int ans= -INF;
for (int i= 1; i<= n; ++i){
for (int j= 1; j<= i; ++j){
scanf("%d", bd[i]+j);
}
}
memset(bd+n+1, -1, sizeof(bd[0]));
for (int i= 1; i<= n; ++i){
for (int j= 1; j<= i; ++j){
if (!bd[i][j]){
int tmp= 0;
memset(vis, 0, sizeof(vis));
bd[i][j]= c;
for (int x= 1; x<= n; ++x){
for (int y= 1; y<= x; ++y){
if (vis[x][y]){
continue;
}
if (c== bd[x][y]){
tmp-= dfs(x, y);
}
else{
tmp+= dfs(x, y);
}
}
}
bd[i][j]= 0;
ans= max(ans, tmp);
}
}
}
printf("%d\n", ans);
}
return 0;
}