题目:http://acm.hdu.edu.cn/showproblem.php?pid=3375
题意:给你一个由/和构成的图,求图中不是用作分割图形的/和的数量
这个题最坑的是n,m是反的!!!
一种简单直接的方法是将/或放大成3*3,然后直接染色,判断
#include<iostream> #include<cstdio> #include<cstring> #include<string> #include<cmath> #include<algorithm> #include<vector> #include<queue> #include<stack> #include<map> #include<set> using namespace std; char c[505]; int a[1505][1505]; int fx[4]={0,0,-1,1}; int fy[4]={1,-1,0,0}; int stx[1505*1505],sty[1505*1505]; int color; int n,m; void dfs(int x,int y) { int top=0; stx[top]=x; sty[top++]=y; a[x][y]=color; while(top!=0) { x=stx[--top]; y=sty[top]; for(int i=0;i<4;i++) { int tx=fx[i]+x,ty=fy[i]+y; if (tx<0||tx>=n||ty<0||ty>=m) continue; if (a[tx][ty]==0) { a[tx][ty]=color; stx[top]=tx; sty[top++]=ty; } } } } bool check(int x,int y) { int t=-1; for(int i=0;i<4;i++) { int tx=fx[i]+x,ty=fy[i]+y; if (tx<0||tx>=n||ty<0||ty>=m) continue; if (t==-1) { if (a[tx][ty]!=-1) t=a[tx][ty]; } else { if (a[tx][ty]==-1) continue; if (t!=a[tx][ty]) return false; } } return true; } int main() { while(scanf("%d%d",&m,&n)!=EOF) { n*=3;m*=3; for(int i=0;i<n;i++) for(int j=0;j<m;j++) a[i][j]=0; n/=3;m/=3; for(int i=0;i<n;i++) { scanf("%s",c); for(int j=0;j<m;j++) { if (c[j]=='\') { a[i*3][j*3]=-1; a[i*3+1][j*3+1]=-1; a[i*3+2][j*3+2]=-1; } else if (c[j]=='/') { a[i*3][j*3+2]=-1; a[i*3+1][j*3+1]=-1; a[i*3+2][j*3]=-1; } } } n*=3;m*=3; color=0; for(int i=0;i<n;i++) for(int j=0;j<m;j++) if (a[i][j]==0) { color++; dfs(i,j); } int ans=0; for(int i=0;i<n;i++) for(int j=0;j<m;j++) if (a[i][j]==-1) if (check(i,j)) ans++; printf("%d ",ans/3); } return 0; }
但是还有更好的方法,将一个/或分成2半
看看和当前这一半相邻的是否可以染色
染完色以后只需要看每格的两半是否是同色就行了
特别注意只有1格的情况,分成两半无法bfs,也就无法染色
#include<iostream> #include<cstdio> #include<cstring> #include<string> #include<cmath> #include<algorithm> #include<vector> #include<queue> #include<stack> #include<map> #include<set> using namespace std; const int N=505; struct pp { char ch; int l[2]; }; pp a[N][N]; struct p { int x,y,op; p(int xx,int yy,int opp) { x=xx; y=yy; op=opp; } }; int n,m,color; char s[N]; queue<p> que; bool pd(int x,int y) { return (x>=0&&x<n&&y>=0&&y<m); } void add(int x,int y,int op) { if (pd(x,y)&&a[x][y].l[op]==-1) { a[x][y].l[op]=color; que.push(p(x,y,op)); } } void bfs(int xx,int yy,int opp) { que.push(p(xx,yy,opp)); while(!que.empty()) { p t=que.front(); que.pop(); int x=t.x,y=t.y,op=t.op; if (a[x][y].ch=='/') { if (op==0) { add(x-1,y,!op); if (a[x][y-1].ch=='\') add(x,y-1,op); else add(x,y-1,!op); } else { add(x+1,y,!op); if (a[x][y+1].ch=='\') add(x,y+1,op); else add(x,y+1,!op); } } else { if (op==0) { add(x-1,y,!op); if (a[x][y+1].ch=='/') add(x,y+1,op); else add(x,y+1,!op); } else { add(x+1,y,!op); if (a[x][y-1].ch=='/') add(x,y-1,op); else add(x,y-1,!op); } } } } int main() { while(scanf("%d%d",&m,&n)!=EOF) { for(int i=0;i<n;i++) { scanf("%s",s); for(int j=0;j<m;j++) { a[i][j].ch=s[j]; a[i][j].l[0]=a[i][j].l[1]=-1; } } if (n==1&&m==1) {printf("0 ");continue;} color=0; for(int i=0;i<n;i++) for(int j=0;j<m;j++) for(int k=0;k<2;k++) if (a[i][j].l[k]==-1) { ++color; bfs(i,j,k); } int ans=0; for(int i=0;i<n;i++) for(int j=0;j<m;j++) if (a[i][j].l[0]==a[i][j].l[1]) ans++; printf("%d ",ans); } return 0; }