`

南阳理工OJ 92 图像有用区域 宽度优先遍历

 
阅读更多
/*
这道题本来用广度递归来实现,编写完后发现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);
}

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics