/* 长记性了,以后对大数组初始化要注意了!140ms 原来是对vis数组进行每次初始化,每次初始化要200*200的复杂度 一直超时,发现没必要这样,直接标记点就行了,只需要一个15的数组用来标记,vis数组用来映射坐标就行了 然后就是暴力加了一点优化,下面没有加优化。 */ #include<stdio.h> #include<string.h> #define inf 0x3fffffff #define N 210 int vis[N][N]; char s[N][N]; int vss[20]; struct node { int x,y; } fp[N],ff[N]; int dd(int xx,int yy) { if(!vss[vis[xx][yy]]) { vss[vis[xx][yy]]++; return 1; } else vss[vis[xx][yy]]++; return 0; } int flag[N]; int x1,y1,x2,y2; void td(int k) { if(k==0) { x1=-1; y1=0; x2=0; y2=1; } if(k==1) { x2=0; y2=1; x1=1; y1=0; } if(k==2) { x2=0; y2=-1; x1=1; y1=0; } if(k==3) { x2=0; y2=-1; x1=-1; y1=0; } return ; } int n,m; int judge(int xx,int yy) { if(xx>=1&&xx<=n&&yy>=1&&yy<=m) return 1; return 0; } void init(int xx,int yy) { vss[vis[xx+x1][yy+y1]]--; vss[vis[xx+x2][yy+y2]]--; vss[vis[xx][yy+1]]++; vss[vis[xx-1][yy]]++; } int main() { int i,j,k,cnt,cur,maxx,num; while(scanf("%d%d",&n,&m),n||m) { for(i=1; i<=n; i++) scanf("%s",s[i]+1); cnt=0; maxx=inf; memset(vis,0,sizeof(vis)); for(i=1; i<=n; i++) for(j=1; j<=m; j++) if(s[i][j]=='.') { fp[++cnt].x=i; fp[cnt].y=j; vis[i][j]=cnt; } if(cnt==0) { printf("0 "); continue; } for(i=0; i<(1<<cnt); i++) { memset(vss,0,sizeof(vss)); int len=0; // if(i!=18)continue; // printf("i=%d ",i); for(j=0; j<cnt; j++) if(i&(1<<j)) { ff[len].x=fp[j+1].x; ff[len++].y=fp[j+1].y; // printf("j=%d ",j+1); } // printf("%d ",len); int xx,yy,nu=0; num=0; for(cur=0; cur<len; cur++) { xx=ff[cur].x,yy=ff[cur].y; num+=dd(xx,yy); if(judge(xx,yy+1)) { if(s[xx][yy+1]=='#') nu++; else num+=dd(xx,yy+1); } if(judge(xx-1,yy)) { if(s[xx-1][yy]=='#') nu++; else num+=dd(xx-1,yy); } } // printf("len=%d %d %d ",len,num,nu); int nuk,xv,yv,nn,flag; for(j=0;j<len;j++) for(k=0;k<4;k++) { nuk=0;nn=0;flag=0;xv=0;yv=0; xx=ff[j].x;yy=ff[j].y; // printf("%d %d %d ",xx,yy+1,vis[xx][yy+1]); if(judge(xx,yy+1)) { if(s[xx][yy+1]=='#') nuk++; else if(vss[vis[xx][yy+1]]==1) { nn++; vss[vis[xx][yy+1]]--; } else vss[vis[xx][yy+1]]--; } if(judge(xx-1,yy)) { if(s[xx-1][yy]=='#') nuk++; else if(vss[vis[xx-1][yy]]==1) { nn++; vss[vis[xx-1][yy]]--; } else vss[vis[xx-1][yy]]--; } td(k); // printf("x1=%d %d %d ",xx+x1,yy+y1,vis[xx+x1][yy+y1]); if(judge(xx+x1,yy+y1)) { if(s[xx+x1][yy+y1]=='#') flag=1; else xv=dd(xx+x1,yy+y1); } // printf("x2=%d %d %d ",xx+x2,yy+y2,vis[xx+x2][yy+y2]); if(judge(xx+x2,yy+y2)) { if(s[xx+x2][yy+y2]=='#') flag=1; else yv=dd(xx+x2,yy+y2); } init(xx,yy); // printf("nuk=%d %d %d %d %d %d ",nuk,k,j,xv,yv,nn); if(nu==nuk&&num-nn+xv+yv==cnt&&!flag) { // printf("z=%d %d %d ",j,k,num); // if(len==2)printf("%d %d %d ",i,j,k); if(maxx>len) maxx=len; break; } } // printf("%d %d ",cur,num); } if(maxx==inf) printf("-1 "); else printf("%d ",maxx); } return 0; }
/* 343ms 纯暴力 */ #include<stdio.h> #include<string.h> #define inf 0x3fffffff #define N 300 int vis[N][N]; char s[N][N]; int vss[N]; struct node { int x,y; } fp[N],ff[N]; int dd(int xx,int yy) { if(!vss[vis[xx][yy]]) { vss[vis[xx][yy]]=1; return 1; } return 0; } int x1,y1,x2,y2; void td(int k) { if(k==0) { x1=-1; y1=0; x2=0; y2=1; } if(k==1) { x2=0; y2=1; x1=1; y1=0; } if(k==2) { x2=0; y2=-1; x1=1; y1=0; } if(k==3) { x2=0; y2=-1; x1=-1; y1=0; } return ; } int n,m; int judge(int xx,int yy) { if(xx>=1&&xx<=n&&yy>=1&&yy<=m) return 1; return 0; } int main() { int i,j,k,cnt,cur,maxx,ok; while(scanf("%d%d",&n,&m),n||m) { for(i=1; i<=n; i++) scanf("%s",s[i]+1); cnt=0; maxx=inf; for(i=1; i<=n; i++) for(j=1; j<=m; j++) if(s[i][j]=='.') { fp[++cnt].x=i; fp[cnt].y=j; vis[i][j]=cnt; } if(cnt==0) { printf("0 "); continue; } for(i=0; i<(1<<cnt); i++) { int len=0; for(j=0; j<cnt; j++) if(i&(1<<j)) { ff[len].x=fp[j+1].x; ff[len++].y=fp[j+1].y; } // printf("%d ",len); for(j=0; j<len; j++) for(k=0; k<4; k++) { memset(vss,0,sizeof(vss)); int xx=ff[j].x,yy=ff[j].y; int num=0; num+=dd(xx,yy); td(k); // printf("%d %d %d",k,xx+x1,yy+y1); if(judge(xx+x1,yy+y1)) { if(s[xx+x1][yy+y1]=='#')continue; num+=dd(xx+x1,yy+y1); } if(judge(xx+x2,yy+y2)) { if(s[xx+x2][yy+y2]=='#')continue;; num+=dd(xx+x2,yy+y2); } for(cur=0; cur<len; cur++) { if(cur==j)continue; xx=ff[cur].x,yy=ff[cur].y; num+=dd(xx,yy); if(judge(xx,yy+1)) { if(s[xx][yy+1]=='#')break; num+=dd(xx,yy+1); } if(judge(xx-1,yy)) { if(s[xx-1][yy]=='#')break; num+=dd(xx-1,yy); } } // printf("%d %d ",cur,num); if(cur==len) { if(num==cnt) { if(maxx>len) maxx=len; break; } } } } if(maxx==inf) printf("-1 "); else printf("%d ",maxx); } return 0; }