• Codeforces 884E E. Binary Matrix


      OvO http://codeforces.com/contest/884/problem/E

      884e

      考虑并查集,每个点向上方和左方的点合并,答案即为1的总数减去需要合并的次数

      由于只有16MB,考虑动态数组

      由于动态数组,则并查集的时候需要一些细节处理,略OVO

      而且还卡常数

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <cmath>
    #include <algorithm>
    
    using namespace std;
    namespace fastIO {  
        #define BUF_SIZE 100000  
        //fread -> read  
        bool IOerror = 0;  
        inline char nc() {  
            static char buf[BUF_SIZE], *p1 = buf + BUF_SIZE, *pend = buf + BUF_SIZE;  
            if(p1 == pend) {  
                p1 = buf;  
                pend = buf + fread(buf, 1, BUF_SIZE, stdin);  
                if(pend == p1) {  
                    IOerror = 1;  
                    return -1;  
                }  
            }  
            return *p1++;  
        }  
        inline bool blank(char ch) {  
            return ch == ' ' || ch == '
    ' || ch == '
    ' || ch == '	';  
        }  
        inline bool read(int &x) {  
            char ch;  
            while(blank(ch = nc()));  
            if(IOerror)  
                return false;  
            for(x = ch - '0'; (ch = nc()) >= '0' && ch <= '9'; x = x * 10 + ch - '0');  
            return true;
        }   
    	inline void read(char *s){
            char ch=nc();
            for (;blank(ch);ch=nc());
            if (IOerror)return;
            for (;!blank(ch)&&!IOerror;ch=nc())*s++=ch;
            *s=0;
        }
        #undef BUF_SIZE  
    };  
    using namespace fastIO; 
    
    const int M=(1<<14)+14;
    int ma[M*2],n,m,id;
    bool mp[2][M];
    int dx[3]={0,0,-1};
    int dy[3]={0,-1,0};
    int ans;
    char s[M/4];
    
    inline int xnum(char spl)
    {
    	if(spl>='A' && spl<='F')
    		return spl-'A'+10;
    	else
    		return spl-'0';
    }
    
    //inline int getpos(int x,int y)
    //{
    //	return (x-1)*m+y;
    //}
    
    inline int xgetpos(int x,int y)
    {
    	return (x-id+1-1)*m+y+m;
    }
    
    //inline void getxy(int pos,int &x,int &y)
    //{
    //	y=(pos-1)%m+1;
    //	x=(pos-y)/m+1-id+1; 
    //}
    
    inline int fff(int pos)
    {
    	if(ma[pos]==pos) return pos;
    	return ma[pos]=fff(ma[pos]);
    }
    
    inline bool check(int x,int y)
    {
    	if(x<=0 || y<=0 || x>n || y>m || mp[x-id+1][y]==0)
    		return false;
    	return true;
    }
    
    void deal(int x,int y)
    {
    	int i,j,x0,y0,pos,pos0,p,p0,xx,xy,xx0,xy0;
    	pos=xgetpos(x,y);
    	for(i=1;i<=2;i++)
    	{
    		x0=x+dx[i]; y0=y+dy[i];
    		if(check(x0,y0)==false) continue;
    		pos0=xgetpos(x0,y0);
    		p=fff(pos); p0=fff(pos0);
    		if(p!=p0)
    		{
    			ans--;
    			ma[p0]=p;
    		}
    	}
    }
    
    void xread()
    {
    	int i,j,t,num;
    //	char chr;
    //	getchar();
    	read(s+1);
    	for(j=1;j<=m/4;j++)
    	{
    //		chr=getchar();
    //		num=xnum(chr);
    		num=xnum(s[j]);
    		for(t=4;t>=1;t--)
    		{
    			mp[1][(j-1)*4+t]=num&1;
    			if(num&1) ans++;
    //			cout<<(num&1)<<' ';
    			num>>=1;
    		}
    	}
    //	cout<<endl;
    }
    
    void solve()
    {
    	int i,j,pos;
    	ans=0;
    	for(i=1;i<=n;i++)
    	{
    		id=i;
    		for(j=1;j<=m;j++)
    			mp[0][j]=mp[1][j],ma[j]=ma[m+j]-m;
    		xread();
    		for(j=1;j<=m;j++)
    			if(mp[1][j])
    			{
    				pos=xgetpos(i,j);
    				ma[m+j]=pos;
    			}
    		for(j=1;j<=m;j++)
    		{
    			if(mp[1][j])
    				deal(i,j);
    		}
    	}
    	printf("%d
    ",ans);
    }
    
    int main()
    {
    //	freopen("e.in","r",stdin);
    	int i,j,t,num,tmp;
    	read(n); read(m);
    	solve();
    	return 0;
    }
    

      

  • 相关阅读:
    Android状态栏和导航栏
    ScrollView小记
    iOS本地推送
    java-集合框架-泛型1
    java-集合框架4---foreach使用--for的增强使用
    java-集合框架3-迭代器的使用
    JAVA-集合框架2
    Number 数据类型转化 NaN 函数isNaN
    数据类型分类
    VScode 插件推荐安装
  • 原文地址:https://www.cnblogs.com/FxxL/p/7806279.html
Copyright © 2020-2023  润新知