zoukankan      html  css  js  c++  java
  • HDU 4775 Infinite Go 并查集+模拟

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=4775

    题意:在一个只有左和上边界的棋盘上下围棋,如果被围死就被吃掉,求最后黑色和白色棋子的个数

    我们可以利用并查集来保存连通块,同时维护这个连通块周围的空格数,如果空格数为0,则删去这个连通块,同时返还给其他连通块空格数

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<cmath>
    #include<algorithm>
    #include<vector>
    #include<queue>
    #include<stack>
    #include<map>
    #include<set>
    #define p make_pair
    using namespace std;
    const int N=1e4+5;
    map<pair<int,int>,int> ma;
    int fx[4]={0,0,1,-1};
    int fy[4]={1,-1,0,0};
    int f[N],fre[N];//父节点和空格数目
    int cnt[2];//棋子数目
    int Find(int x)
    {
        return f[x]==x?x:f[x]=Find(f[x]);
    }
    int check(int x,int y)//判断是否为空格
    {
        if (x==0||y==0) return 0;
        if (ma.find(p(x,y))==ma.end()) return 1;
        int t=ma[p(x,y)];
        fre[Find(t)]--;
        return 0;
    }
    void hb(int x,int y,int xx,int yy)//合并连通块
    {
        if (x==0||y==0) return;
        if (ma.find(p(xx,yy))==ma.end()) return;
        int t=ma[p(x,y)];
        int ft=Find(t);
        int tt=ma[p(xx,yy)];
        int ftt=Find(tt);
        if (ft!=ftt)
            if (t%2==tt%2)
        {
            fre[ft]+=fre[ftt];
            f[ftt]=ft;
        }
    }
    void Clear(int x,int y,int col)//清除连通块
    {
        if (x==0||y==0) return;
        if (ma.find(p(x,y))==ma.end()) return;
        int t=ma[p(x,y)];
        if (t%2!=col)
        {
            fre[Find(t)]++;
            return;
        }
        cnt[col]--;
        ma.erase(p(x,y));
        for(int i=0;i<4;i++)
            Clear(x+fx[i],y+fy[i],col);
    }
    void xc(int x,int y,int col)//判断是否需要消除
    {
        if (x==0||y==0) return;
        if (ma.find(p(x,y))==ma.end()) return;
        int t=ma[p(x,y)];
        if (t%2!=col) return;
        if (fre[Find(t)]==0) Clear(x,y,col);
    }
    int main()
    {
        int T;
        scanf("%d",&T);
        while(T--)
        {
            cnt[0]=cnt[1]=0;
            ma.clear();
            int n;
            scanf("%d",&n);
            for(int i=1;i<=n;i++)
            {
                f[i]=i;
                fre[i]=0;
            }
            for(int i=1;i<=n;i++)
            {
                int x,y;
                scanf("%d%d",&x,&y);
                cnt[i&1]++;
                ma[p(x,y)]=i;
                for(int j=0;j<4;j++)
                    fre[i]+=check(x+fx[j],y+fy[j]);
                for(int j=0;j<4;j++)
                    hb(x,y,x+fx[j],y+fy[j]);
                for(int j=0;j<4;j++)
                    xc(x+fx[j],y+fy[j],(i&1)^1);
                xc(x,y,i&1);
            }
            printf("%d %d
    ",cnt[1],cnt[0]);
        }
        return 0;
    }
    

      

  • 相关阅读:
    securefile allocation chunks
    脚本:Segment Space Usage Explorer
    Script:10g中不用EM显示Active Session Count by Wait Class
    理解IMPDP ORA19505、ORA31640错误
    了解ocssd.bin如何控制RAC节点重启
    Oracle等待事件:NULL EVENT
    LGWR TRACE Warning: log write time
    MySql隔离级别多线程并发读取数据时的正确性
    Oracle事务处理—隔离级别
    Oracle函数详解
  • 原文地址:https://www.cnblogs.com/bk-201/p/7450310.html
Copyright © 2011-2022 走看看