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 == '\n' || ch == '\r' || ch == '\t';  
    }  
    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\n",ans);
}

int main()
{
//	freopen("e.in","r",stdin);
	int i,j,t,num,tmp;
	read(n); read(m);
	solve();
	return 0;
}

  

 

posted @ 2017-11-08 21:23  太阳星人FxxL  阅读(874)  评论(0编辑  收藏  举报