hdu 3375 XieGang and FanXieGang 斜杠构图 bfs

在图中寻找同色墙即内墙的个数,斜杠图的构图简单直接的一个方法是把杠放在3*3的矩阵中,再进行基本的搜索,但扩大9倍的规模会超时,一个杠还可以按照杠分开的区域分成4部分存储,即扩大4倍的规模,在遍历比较大的图时dfs往往会栈溢出,此时应用非递归的bfs对图遍历

另外数据很多大初始化用memset很占时间会超时,不如for循环快

相邻格子的块号是(r+2)%4,本格内相邻是3-r或(5-r)%4

XieGang and FanXieGangg

Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 306    Accepted Submission(s): 90


Problem Description
  As we know, ‘/’ in chinese is “Xie Gang”, and ‘\’ is “Fan Xie Gang”, we can use them to build a beautiful labyrinth, for example :

here ‘/’ and ‘\’ in the labyrinth means walls, the wall which can’t separate two rooms we call it “inner wall”, for example, in he figure below, there are three “inner wall”s.

 

Input
  There are no more than 20000 cases. each case contains two integers n and m(n,m<=500), the width and the height of the labyrinth, The next m lines represent the labyrinth itself, and contain n characters each, all these characters will be "/" or "\".
 

Output
  Output one integer represents the number of “inner wall”.
 

Sample Input
  
  
3 3 \/\ /\\ /\/ 4 4 \\\\ \\\\
 

Sample Output
  
  
2 0
 
#include<stdio.h>
#include<string.h>
#include<queue>
using namespace std;
#define max 510
int mo[4][2]={ {-1,0}, {0,1}, {1,0}, {0,-1} };
struct node{
	int ge[4];
	int vis[4];
	int fuhao;
}map[max][max];
struct data{           //每个1/4区域 map[x][y]的第g块
	int x,y,g;  
}d[max][max][4]; 
int m,n,color,white;
void bfs(int x,int y,int r)      //染色
{
	queue <data> q;
	int i,j,k;
	if(map[x][y].vis[r])
		return;
	data t;
	t.x=x;t.y=y;t.g=r;
	q.push(t);
	map[x][y].vis[r]=1;
	map[x][y].ge[r]=color;
	while(!q.empty())
	{
		data p;
		p=q.front();
		q.pop();
		i=p.x;
		j=p.y;
		k=p.g;
		if(map[i][j].fuhao=='\\')
		{
			if(map[i][j].vis[(5-k)%4]==0)  //本格
			{
				q.push(d[i][j][(5-k)%4]);
				map[i][j].vis[(5-k)%4]=1;
				map[i][j].ge[(5-k)%4]=color;
			}
			if(0<=i+mo[k][0]&&i+mo[k][0]<m && 0<=j+mo[k][1]&&j+mo[k][1]<n)
			{
				if(map[i+mo[k][0]][j+mo[k][1]].vis[(k+2)%4]==0)
				{
					map[i+mo[k][0]][j+mo[k][1]].vis[(k+2)%4]=1;
					map[i+mo[k][0]][j+mo[k][1]].ge[(k+2)%4]=color;
					q.push(d[i+mo[k][0]][j+mo[k][1]][(k+2)%4]);
				}
			}
		}
		else
		{
			if(map[i][j].vis[3-k]==0)  //本格
			{
				q.push(d[i][j][3-k]);
				map[i][j].vis[3-k]=1;
				map[i][j].ge[3-k]=color;
			}
			if(0<=i+mo[k][0]&&i+mo[k][0]<m && 0<=j+mo[k][1]&&j+mo[k][1]<n)
			{
				if(map[i+mo[k][0]][j+mo[k][1]].vis[(k+2)%4]==0)
				{
					map[i+mo[k][0]][j+mo[k][1]].vis[(k+2)%4]=1;
					map[i+mo[k][0]][j+mo[k][1]].ge[(k+2)%4]=color;
					q.push(d[i+mo[k][0]][j+mo[k][1]][(k+2)%4]);
				}
			}
		}
	}
}
void init()
{
	int i,j,k;
	for(i=0;i<m;i++)
	{
		for(j=0;j<n;j++)
			for(k=0;k<4;k++)
			{
				map[i][j].vis[k]=0;
				map[i][j].fuhao=0;
				map[i][j].ge[k]=0;
			}
	}
}
int main()
{
	int i,j,k;
	while(scanf("%d %d",&n,&m)!=EOF)
	{
		getchar();
		//memset(map,0,sizeof(map));  //会超时
		init();
		color=0;
		white=0;
		for(i=0;i<m;i++)
		{
			for(j=0;j<n;j++)
			{
				scanf("%c",&map[i][j].fuhao);
				for(k=0;k<4;k++)
				{
					d[i][j][k].x=i;
					d[i][j][k].y=j;
					d[i][j][k].g=k;
				}
			}
			
			getchar();
		}
		for(i=0;i<m;i++)
		{
			for(j=0;j<n;j++)
			{
				for(k=0;k<4;k++)
				{
					if(map[i][j].vis[k]==0)
					{
						color++;
						bfs(i,j,k);
					}
				}
			}
		}
		for(i=0;i<m;i++)
		{
			for(j=0;j<n;j++)
			{
				int flag=0,t=map[i][j].ge[0];
				for(k=1;k<4;k++)
				{
					if(t!=map[i][j].ge[k])
					{
						flag=1;
						break;
					}
				}
				if(!flag)
					white++;
			}
		}
		printf("%d\n",white);
	}
	return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值