hdu 4056 zoj 3544 Draw a Mess

链接: https://cn.vjudge.net/problem/HDU-4056

题意: 就问涂完所有的颜色后每种颜色有多少个(共9种)

思路: 想到并查集来做就是个很简单的题,想不到就gg。另外更新的时候对于n一层层更新并且对于q从后向前更新。这样更新过的就没有必要再更新了。

代码:

#include<bits/stdc++.h>

using namespace std;
typedef long long ll;
const int N = 205;
const int M = 50005;

int nxt[M];
int mp[M];
int n,m,q;
char op[15];

int getf(int x)
{
    return nxt[x]==x?x:(nxt[x]=getf(nxt[x]));
}

void update(int L,int R,int col)
{
    for(int y=L; y<=R;)
    {
        y=getf(y);
        if(y<=R)
        {
            mp[y]=col;
            nxt[y]=y+1;
            y++;
        }
        else
            break;
    }
}

void CCC(int tx,int x,int y,int r,int col)
{
    int L,R;
    int jud=abs(tx-x);
    if(jud>r)
        return ;
    jud=r*r-jud*jud;
    jud=sqrt(jud);
    L=max(y-jud,0);
    R=min(y+jud,m-1);
    update(L,R,col);
}

void DDD(int tx,int x,int y,int r,int col)
{
    int L,R;
    int jud=abs(tx-x);
    if(jud>r)
        return ;
    jud=r-jud;
    L=max(y-jud,0);
    R=min(y+jud,m-1);
    update(L,R,col);
}

void RRR(int tx,int x,int y,int l,int w,int col)
{
    if(tx<x)
        return;
    if(tx>x+l-1)
        return ;
    int L,R;
    L=y;
    R=min(y+w-1,m-1);
    update(L,R,col);
}

void TTT(int L,int R,int col)
{
    update(L,R,col);
}

struct node
{
    int op;
    int x,y;
    int col;
    int r,l,w;
    int L,R;
    int down,up;
} xun[M];

int main()
{
    while(scanf("%d %d %d",&n,&m,&q)!=EOF)
    {
        for(int i=1; i<=q; i++)
        {
            scanf("%s",op);
            if(op[0]=='C')
            {
                xun[i].op=1;
                scanf("%d %d %d %d",&xun[i].x, &xun[i].y, &xun[i].r, &xun[i].col);
            }
            else if(op[0]=='D')
            {
                xun[i].op=2;
                scanf("%d %d %d %d",&xun[i].x, &xun[i].y, &xun[i].r, &xun[i].col);
            }
            else if(op[0]=='R')
            {
                xun[i].op=3;
                scanf("%d %d %d %d %d",&xun[i].x, &xun[i].y,&xun[i].l, &xun[i].w, &xun[i].col);
            }
            else if(op[0]=='T')
            {
                xun[i].op=4;
                scanf("%d %d %d %d",&xun[i].x, &xun[i].y, &xun[i].w, &xun[i].col);
                int w=xun[i].w;
                int H=(w+1)/2;
                int tmp=w/2,tmp1,tmp2;
                int L=xun[i].y-tmp;
                int R=xun[i].y+tmp;
                xun[i].L=L;
                xun[i].R=R;
                xun[i].down=xun[i].x;
                xun[i].up=xun[i].down+H-1;
            }
        }

        int cnt[15];
        memset(cnt,0,sizeof(cnt));
        for(int ceng=0; ceng<n; ceng++)
        {
            for(int j=0; j<=m+2; j++)
            {
                mp[j]=0;
                nxt[j]=j;
            }

            for(int i=q; i>=1; i--)
            {
                if(xun[i].op==1)
                {
                    CCC(ceng,xun[i].x,xun[i].y,xun[i].r,xun[i].col);
                }
                else if(xun[i].op==2)
                {
                    DDD(ceng,xun[i].x,xun[i].y,xun[i].r,xun[i].col);
                }
                else if(xun[i].op==3)
                {
                    RRR(ceng,xun[i].x,xun[i].y,xun[i].l,xun[i].w,xun[i].col);
                }
                else if(xun[i].op==4)
                {
                    int L,R;
                    L=max(0,xun[i].L);
                    R=min(m-1,xun[i].R);
                    if(ceng>=xun[i].down&&ceng<=xun[i].up)
                    {
                        TTT(L,R,xun[i].col);
                        xun[i].L++;
                        xun[i].R--;
                    }
                }

            }

            for(int j=0; j<m; j++)
            {
                cnt[mp[j]]++;
            }
        }

        for(int i=1; i<=9; i++)
        {
            if(i==9)
                printf("%d\n",cnt[i]);
            else
                printf("%d ",cnt[i]);
        }
    }
    return 0;
}

 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值