/* 这道题本来用广度递归来实现,编写完后发现AC不了,想想应该是 爆栈了,后来有改成用广度队列来写,可以AC啦! 思路是: 考虑到圈外的点肯定会和边框相交,所以就先把四条边的非0点入队, 入队一个点,就把这个点变成0, 然后在队列里面做第一个元素,找他的上下左右四个相邻非0点入队, 然后在队列里面做第二个元素,找他的上下左右四个相邻非0点入队, .............. 一直到top==base */ #include<stdio.h> #include<string.h> int map[965][1445];//存图 int queue[960*1440];//队列 int fang[4][2]={-1,0,1,0,0,-1,0,1};//方向数组 int W,H,base,top; int main() { // freopen("in.txt","r",stdin); int T; int i,j; scanf("%d",&T); while(T--) { base=0;top=0; memset(map,0,sizeof(map));//初始化 scanf("%d%d",&W,&H); for(i=1;i<=H;i++) for(j=1;j<=W;j++) scanf("%d",&map[i][j]);//存图 for(i=1;i<=H;i++)//第一行与最后一行入队 { if(map[i][1])queue[top++]=i*10000+1,map[i][1]=0;//用整形数存放坐标(节约空间,人人有责!) if(map[i][W])queue[top++]=i*10000+W,map[i][W]=0;//别忘了标记访问过的map为0哦! } for(j=1;j<=W;j++)//第一列与最后一列入队 { if(map[1][j])queue[top++]=1*10000+j,map[1][j]=0; if(map[H][j])queue[top++]=H*10000+j,map[H][j]=0; } while(top!=base)//一直到队列为空 { int x1,y1; for(i=0;i<4;i++) { x1=queue[base]/10000+fang[i][0]; y1=queue[base]%10000+fang[i][1];//求出这个点四周的坐标 if(map[x1][y1]) { queue[top++]=x1*10000+y1;//入队 map[x1][y1]=0;//标记 } } base++;//别忘记了哦! } for(i=1;i<=H;i++)//按格式输出 { for(j=1;j<W;j++)printf("%d ",map[i][j]); printf("%d\n",map[i][W]); } } return(0); }