如果两个坏椰子在八个方向上相邻,就算做相邻,把多个坏椰子相邻的分为一块
把每块坏椰子单独抠出来,放到小图里(200*200),然后看有多少好椰子被坏椰子包围
要注意边界的处理,如果小图在某个边界上,这个边界就视为坏椰子
把被坏椰子包围的sum算出来,剩下的就是n*m-sum-坏椰子个数
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
const int N = 200 + 10;
const int dx[] = {0, 0, -1, 1, -1, 1, -1, 1};
const int dy[] = {-1, 1, 0, 0, -1, 1, 1, -1};
typedef long long ll;
struct node
{
int x, y;
node(int a, int b)
{
x = a;
y = b;
}
bool operator&(const node &u) const
{
for (int i = 0; i < 8; i++)
if (u.x + dx[i] == x && u.y + dy[i] == y)
return true;
return false;
}
};
int a[N][N];
bool vis[N][N];
int num;
bool ff;
void dfs(int x, int y, int an, int am)
{
if (x == 0 || y == 0 || x == an - 1 || y == am - 1)
{
if (a[x][y] == 0)
ff = false;
return;
}
vis[x][y] = true;
num++;
for (int i = 0; i < 4; i++)
{
int nx = x + dx[i], ny = y + dy[i];
if (!vis[nx][ny] && a[nx][ny] != 1)
{
dfs(nx, ny, an, am);
}
}
}
int main()
{
int T, kase = 0;
scanf("%d", &T);
ll n, m;
int k;
while (T--)
{
scanf("%lld%lld", &n, &m);
scanf("%d", &k);
vector<node> v[10 * N];
int cnt = 0;
int x, y;
for (int i = 0; i < k; i++)
{
scanf("%d%d", &x, &y);
bool flag = false;
int pos = -1;
for (int j = 0; !flag && j < cnt; j++)
for (int p = 0; p < v[j].size(); p++)
{
if (v[j][p] & node(x, y))
{
v[j].push_back(node(x, y));
flag = true;
pos = j;
break;
}
}
if (!flag)
{
v[cnt].push_back(node(x, y));
cnt++;
}
else
{
node u = node(x, y);
for (int j = 0; j < cnt; j++)
{
if (j == pos)
continue;
for (int p = 0; p < v[j].size(); p++)
{
if (v[j][p] & u)
{
for (int q = 0; q < v[j].size(); q++)
v[pos].push_back(v[j][q]);
v[j].clear();
break;
}
}
}
}
}
ll ans[N];
int anst = 0;
for (int i = 0; i < cnt; i++)
if (v[i].size())
{
int mx = v[i][0].x, my = v[i][0].y;
int mmx = v[i][0].x, mmy = v[i][0].y;
for (int j = 0; j < v[i].size(); j++)
{
mx = min(v[i][j].x, mx);
my = min(v[i][j].y, my);
mmx = max(v[i][j].x, mmx);
mmy = max(v[i][j].y, mmy);
}
memset(a, 0, sizeof(a));
int an = mmx - mx + 3, am = mmy - my + 3;
for (int j = 0; j < v[i].size(); j++)
{
a[v[i][j].x - mx + 1][v[i][j].y - my + 1] = 1;
}
if (mx == 1)
for (int i = 0; i < am; i++)
a[0][i] = -1;
if (mmx == n)
for (int i = 0; i < am; i++)
a[an - 1][i] = -1;
if (my == 1)
for (int i = 0; i < an; i++)
a[i][0] = -1;
if (mmy == m)
for (int i = 0; i < an; i++)
a[i][am - 1] = -1;
memset(vis, false, sizeof(vis));
for (int i = 1; i < an - 1; i++)
for (int j = 1; j < am - 1; j++)
if (!vis[i][j] && a[i][j] == 0)
{
ff = true;
num = 0;
dfs(i, j, an, am);
if (ff)
ans[anst++] = num;
}
}
ll sum = n * m - k;
for (int i = 0; i < anst; i++)
sum -= ans[i];
ans[anst++] = sum;
sort(ans, ans + anst);
printf("Case #%d:\n", ++kase);
printf("%d\n", anst);
for (int i = 0; i < anst - 1; i++)
printf("%lld ", ans[i]);
printf("%lld\n", ans[anst - 1]);
}
return 0;
}