zoukankan      html  css  js  c++  java
  • gmoj 6814. 【2020.10.06提高组模拟】染色大战

     这是一道sb题,但是考场时我犯了傻逼错误,导致打的程序非常麻烦非常长。

    想法很简单,对于每种颜色维护一个前向星,表示与当前联通块相连通且颜色为i的连通块。

    然后每次找到这个连通块,暴力将这个连通块连向的点继续丢进桶里,因为每个连通块最多进一次桶,每个位置最多遍历一次,所以可以保证时间复杂度。

    #include<cstdio>
    #include<cstring>
    #include<map>
    #include<algorithm>
    #define N 1010
    #define M N*N
    using namespace std;
    int n,m,Q,k,x,y,i,j,s[N][N],cnt,tot,bz[N][N],q[M],sum[M],fa[N][N][3],fp[M][3],ans,bzk[N][N],fx[5][3],bzp[M];
    struct edge{
        int to,next;
    }e[M*10];
    void dfs(int x,int y){
        bz[x][y]=cnt;
        sum[cnt]++;
        int i,xx,yy;
        for (i=1;i<=4;i++){
            xx=x+fx[i][1];yy=y+fx[i][2];
            if (xx>0&&yy>0&&xx<=n&&yy<=m&&s[x][y]==s[xx][yy]&&bz[xx][yy]==0)
                fa[xx][yy][1]=x,fa[xx][yy][2]=y,dfs(xx,yy);
        }
    }
    void insert(int x,int y){
        tot++;
        e[tot].to=y;
        e[tot].next=q[x];
        q[x]=tot;
    }
    void solve(int x,int y){
        int i,xx,yy;
        for (i=1;i<=4;i++){
            xx=x+fx[i][1];yy=y+fx[i][2];
            if (xx>0&&yy>0&&xx<=n&&yy<=m){
                if (fa[xx][yy][1]==x&&fa[xx][yy][2]==y)
                    solve(xx,yy);
                if (bzp[bz[xx][yy]]||s[xx][yy]==s[x][y]) continue;
                bzp[bz[xx][yy]]=1;
                insert(s[xx][yy],bz[xx][yy]);
            }
        }
    }
    int main(){
        freopen("color.in","r",stdin);
        freopen("color.out","w",stdout);
        fx[1][1]=1;fx[1][2]=0;
        fx[2][1]=-1;fx[2][2]=0;
        fx[3][1]=0;fx[3][2]=1;
        fx[4][1]=0;fx[4][2]=-1;
        scanf("%d%d%d%d",&n,&m,&Q,&k);
        for (i=1;i<=n;i++)
            for (j=1;j<=m;j++)
                scanf("%d",&s[i][j]);
        for (i=1;i<=n;i++)
            for (j=1;j<=m;j++)
                if (!bz[i][j]){
                    cnt++;
                    fp[cnt][1]=i;fp[cnt][2]=j;
                    dfs(i,j);
                }
        bzp[1]=1;
        solve(1,1);
        ans=sum[1];
        while (Q--){
            scanf("%d",&x);
            for (i=q[x];i;i=e[i].next){
                y=e[i].to;
                ans+=sum[y];
                solve(fp[y][1],fp[y][2]);
            }
            q[x]=0;
            printf("%d
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    面向对象-对象的内存图
    面向对象-类与对象的关系
    部署Ambari Server实战案例
    面向对象介绍
    基础语法-二维数组的基本使用
    基础语法-无序/有序数组中元素的查找
    常见数据结构与算法-冒泡排序
    常见数据结构与算法-选择排序
    基础语法-数组的常见问题及常见操作
    基础语法-数组的内存分配
  • 原文地址:https://www.cnblogs.com/Mohogany/p/13773757.html
Copyright © 2011-2022 走看看