HDU-5925 Coconuts

如果两个坏椰子在八个方向上相邻,就算做相邻,把多个坏椰子相邻的分为一块

把每块坏椰子单独抠出来,放到小图里(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;
}

猜你喜欢

转载自blog.csdn.net/wl16wzl/article/details/82936064
hdu