HDU5925 2016长春东北赛重现

#include <bits/stdc++.h>

using namespace std;

const int maxn = 450;

struct N{
    long long point;
    int _set;
    long long id;
}x[maxn],y[maxn];

long long Vx[maxn],Vy[maxn];
bool vis[maxn][maxn];

bool cmpPoint(const N &A,const N &B){
    return A.point < B.point;
}
bool cmpId(const N &A,const N &B){
    return A.id < B.id;
}

void Discrete(int n,N *p,int &border,long long *V){
    p[n+1].id = n+1 , p[n+1].point = border;
    p[0].id = 0 , p[0].point = 1;
    sort(p+1,p+n+1,cmpPoint);
    int index = 1;
    V[1] = 1;
    for(int i=1;i<=n+1;i++){
        if(p[i].point == p[i-1].point){
            p[i]._set = index;
        }
        else if(p[i].point - p[i-1].point == 1){
            p[i]._set = ++index;
            V[index] = 1;
        }
        else{
            p[i]._set = index + 2;
            V[index + 2] = 1;
            V[index + 1] = p[i].point - p[i-1].point - 1;
            index += 2;
        }
    }
    border = index;
    sort(p+1,p+n+1,cmpId);
}

long long dfs(int sx,int sy,int R,int C){
    long long sum = Vx[sx] * Vy[sy];
    vis[sx][sy] = true;
    for(int i=-1;i<=1;i++){
        for(int j=-1;j<=1;j++){
            if(i&&j) continue;
            int nx = sx + i;
            int ny = sy + j;
            if(!vis[nx][ny] && nx>0 && ny>0 && nx<=R && ny<=C){
                sum += dfs(nx,ny,R,C);
            }
        }
    }
    return sum;
}

int main()
{
    ios::sync_with_stdio(false);
    int T,cnt=0;
    cin>>T;
    while(T--){
        int R,C;
        cin>>R>>C;
        int n;
        cin>>n;
        for(int i=1;i<=n;i++){
            cin>>x[i].point>>y[i].point;
            x[i].id = y[i].id = i;
        }
        Discrete(n,x,R,Vx);
        Discrete(n,y,C,Vy);
        long long ans[maxn];
        memset(ans,0,sizeof(ans));
        memset(vis,false,sizeof(vis));
        for(int i=1;i<=n;i++) vis[ x[i]._set ][ y[i]._set ] = true;
        int index = 0;
        for(int i=1;i<=R;i++){
            for(int j=1;j<=C;j++){
                if(!vis[i][j]) ans[index++] = dfs(i,j,R,C);
            }
        }
        sort(ans,ans+index);
        cout<<"Case #"<<++cnt<<":"<<endl;
        cout<<index<<endl;
        for(int i=0;i<index;i++)
            cout<<ans[i]<<(i == index-1 ? "\n":" ");
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值