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; }