2016CCPC东北地区大学生程序设计竞赛 - 重现赛 D Coconuts HDU 5925

2016CCPC东北地区大学生程序设计竞赛 - 重现赛 D Coconuts HDU 5925
Coconuts
Time Limit: 9000/4500 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 456 Accepted Submission(s): 132

Problem Description
TanBig, a friend of Mr. Frog, likes eating very much, so he always has dreams about eating. One day, TanBig dreams of a field of coconuts, and the field looks like a large chessboard which has R rows and C columns. In every cell of the field, there is one coconut. Unfortunately, some of the coconuts have gone bad. For sake of his health, TanBig will eat the coconuts following the rule that he can only eat good coconuts and can only eat a connected component of good coconuts one time(you can consider the bad coconuts as barriers, and the good coconuts are 4-connected, which means one coconut in cell (x, y) is connected to (x - 1, y), (x + 1, y), (x, y + 1), (x, y - 1).

Now TanBig wants to know how many times he needs to eat all the good coconuts in the field, and how many coconuts he would eat each time(the area of each 4-connected component).

Input
The first line contains apositiveinteger T(T≤10) which denotes the test cases. T test cases begin from the second line. In every test case, the first line contains two integers R and C, 0

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<string>
#include<iostream>
#include<iomanip>
#include<map>
#include<vector>
#include<queue>
using namespace std;
typedef unsigned long long LL;
const int maxn=400+13;
struct Node{
    int x;
    int y;
    Node(){}
    Node(int _x,int _y):x(_x),y(_y){}
    Node operator + (const Node & A)
    {
        return Node(x+A.x,y+A.y);
    }
};
Node dir[4]={Node(1,0),Node(-1,0),Node(0,1),Node(0,-1)};
int T;
LL R,C;
int n,x[maxn],y[maxn];
int nx[maxn],ny[maxn];
int a[maxn],sz;
map<int,int> mpx,mpy;
LL grad[maxn][maxn];
int wid[maxn],len[maxn];
bool vis[maxn][maxn];
int nr,nc;
vector<LL> ans;
bool ingrad(Node s)
{
    if(s.x<1||s.x>nr)   return 0;
    if(s.y<1||s.y>nc)   return 0;
    return 1;
}
LL bfs(Node s)
{
    Node u,v;
    LL res=0;
    queue<Node> que;
    que.push(s);
    vis[s.x][s.y]=1;
    res+=grad[s.x][s.y];
    while(!que.empty()){
        u=que.front();que.pop();
        for(int i=0;i<4;i++){
            v=u+dir[i];
            if(grad[v.x][v.y]==0)   continue;
            if(vis[v.x][v.y])   continue;
            vis[v.x][v.y]=1;
            res+=grad[v.x][v.y];
            que.push(v);
        }
    }
    return res;
}
void getans(void)
{
    LL tmp=0;
    memset(vis,0,sizeof(vis));
    ans.clear();
    for(int i=1;i<=nr;i++){
        for(int j=1;j<=nc;j++){
            if(grad[i][j]==0)   continue;
            if(vis[i][j])   continue;
            tmp=bfs(Node(i,j));
            ans.push_back(tmp);
        }
    }

}
int sortunion(int a[],int sz)
{
    sort(a,a+sz);
    int i,j;
    for(i=1,j=0;i<sz;i++){
        if(a[i]!=a[j])  a[++j]=a[i];
    }
    return j+1;
}

void solve(void)
{
    if(n==0){
        // cout<<R<<C<<endl;
        printf("1\n%llu\n",1LLU*R*C);
        return ;
    }
            memset(wid,0,sizeof(wid));
            memset(len,0,sizeof(len));
    // 离散处理x
    int p=1;
    memcpy(a,x,sizeof(a));
    sz=sortunion(a,n);
//  for(int i=0;i<sz;i++){
//        printf("%d ",a[i]);
//  }
//  puts("");
    mpx[1]=1;
    len[1]=1;
    if(a[0]==2){
                mpx[a[0]]=++p;
                 len[p]=1;
    }
    else if(a[0]>2){
                p=p+2;mpx[a[0]]=p;
                len[p-1]=a[0]-1-1;
                len[p]=1;
    }

    for(int i=1;i<sz;i++){
        if(a[i]==a[i-1]+1){
            mpx[a[i]]=++p;
            len[p]=1;
        }
        else{
            p=p+2;mpx[a[i]]=p;
            len[p]=1;
            len[p-1]=a[i]-1-a[i-1];
        }
    }
    if(a[sz-1]==R-1){
        mpx[R]=++p;
        len[p]=1;
    }
    else if(a[sz-1]<R-1){
        mpx[R]=p+2;
        len[p+2]=1;
        len[p+1]=R-1-a[sz-1];
        p=p+2;
    }
    nr=p;
    //离散处理y
    p=1;
    memcpy(a,y,sizeof(a));
    sz=sortunion(a,n);
    mpy[1]=1;
    wid[1]=1;
    if(a[0]==2){
        mpy[a[0]]=++p;
        wid[p]=1;
    }
    else if(a[0]>2){
        p=p+2;mpy[a[0]]=p;
        wid[p]=1;
        wid[p-1]=a[0]-1-1;
       }
    for(int i=1;i<sz;i++){
        if(a[i]==a[i-1]+1){
            mpy[a[i]]=++p;
            wid[p]=1;
        }
        else{
            p=p+2;mpy[a[i]]=p;
            wid[p]=1;wid[p-1]=a[i]-a[i-1]-1;
        }

    }
    if(a[sz-1]==C-1){
        mpy[C]=++p;
        wid[p]=1;
    }
    else if(a[sz-1]<C-1){
        mpy[C]=p+2;
        wid[p+1]=C-1-a[sz-1];
        wid[p+2]=1;
        p=p+2;
    }
    nc=p;

    fill(grad[0],grad[0]+maxn*maxn,1);
    for(int i=0;i<n;i++){
        nx[i]=mpx[x[i]];ny[i]=mpy[y[i]];
        grad[nx[i]][ny[i]]=0;
//      cout<<nx[i]<<" "<<ny[i]<<endl;
    }
    for(int i=0;i<maxn;i++){
        grad[0][i]=grad[nr+1][i]=0;
        grad[i][0]=grad[i][nc+1]=0;
    }
    for(int i=0;i<=nr+1;i++){
        for(int j=0;j<=nc+1;j++){
                                if(grad[i][j]!=0)
                                        grad[i][j]=1LL*len[i]*wid[j];
             // printf("%3llu",grad[i][j]);
        }
        // puts("");
    }

    getans();
    sort(ans.begin(),ans.end());
    int all=ans.size();
    printf("%d\n",all);
    for(int i=0;i<all-1;i++){
        printf("%llu ",ans[i]);
    }
    printf("%llu\n",ans[all-1]);
}

int main()
{
    int t=0;
    scanf("%d",&T);
    while(T--){
        memset(x,0,sizeof(x));
        memset(y,0,sizeof(y));
        scanf("%llu %llu",&R,&C);
        scanf("%d",&n);
        for(int i=0;i<n;i++){
            scanf("%d %d",&x[i],&y[i]);
        }
        printf("Case #%d:\n",++t);
        solve();
    }

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值