poj 1164.The Castle

#include<iostream>
using namespace std;

typedef struct node{
	int east,south,west,north;
	bool used;
}Lnode;
int n,m;
int num,area;
Lnode castle[55][55];

void init()
{
	int tsum;
	Lnode nd;
	for(int i=0;i<n;i++)
		for(int j=0;j<m;j++){
			cin>>tsum;
			nd.west=(tsum&(1<<0))>>0;
			nd.north=(tsum&(1<<1))>>1;
			nd.east=(tsum&(1<<2))>>2;
			nd.south=(tsum&(1<<3))>>3;
			nd.used=false;
			castle[i][j]=nd;
			}
}
void dfs(int x,int y,int& depth)
{
	if(x<0||x>n||y<0||y>m)
		return ;
	if(!castle[x][y].used){
		depth++;
		castle[x][y].used=true;
		if(castle[x][y].west==0){
			dfs(x,y-1,depth);
		}
		if(castle[x][y].north==0){
		
			dfs(x-1,y,depth);
		}
		if(castle[x][y].east==0){
		
			dfs(x,y+1,depth);
		}
		if(castle[x][y].south==0){
		
			dfs(x+1,y,depth);
		}
	}
	
	
}
int main()
{
	cin>>n>>m;
	init();
	num=0;
	int max=0;
	for(int i=0;i<n;i++)
		for(int j=0;j<m;j++){
			if(!castle[i][j].used){
				num++;
				area=0;
				dfs(i,j,area);
				if(max<area)
					max=area;
			}
		}
	cout<<num<<endl;
	cout<<max<<endl;
	return 0;
}
//并查集,哈哈
#include <iostream> 
#include <cstring> 
using namespace std;   
int parent[3000];   
int find(int x)    //寻找根节点 和 路径压缩 
{     
	if(parent[x]<0) 
		return x;    
	parent[x]=find(parent[x]); 
    return parent[x]; }   
void uni(int x,int y)  //集合合并 
{     
	int root1,root2,t; 
	root1=find(x);     
	root2=find(y);    
	if(root1==root2) 
		return;      
	t=parent[root1]+parent[root2];  
	if(parent[root1]<parent[root2])  
	{       
		parent[root2]=root1;  
		parent[root1]=t;    
	}  
	else  
	{        
		parent[root1]=root2;
		parent[root2]=t;   
	} 
}   
int main () 
{     
	int n,m,sum,a[3000];  
	while (cin>>n>>m)    
	{      
		memset(parent,-1,sizeof(parent));  
		sum = n * m;      
		for (int i = 1; i <= sum; i++)   
		{           
			cin>>a[i];  
			if (!(a[i] & 1))   
			{                
				if (i%m - 1 > 0) uni(i,i-1);  
             }           
			a[i] /= 2;       
			if (!(a[i] & 1))    
			{                 
				if (i > m) uni(i,i-m);  
           }             
			a[i] /= 2;            
			if (!(a[i] & 1))     
			{               
				if (i%m != 0) uni(i,i+1);
             }          
			a[i] /= 2;     
			if (!(a[i] & 1)) 
            {                
				if (i+m <= sum)
					uni(i,i+m);          
			}          
		 }         
		int max = -1,ans = 0;      
		for (int i = 1; i <= sum; i++)     
		{           
			if (parent[i]*-1 > max) 
				max = parent[i]*-1;    
			if (parent[i] < 0) ans ++;   
	      }       
		cout<<ans<<endl;      
		cout<<max<<endl;   
	}         
	return 0;
 }

#include<stdio.h>
#define DEN 51

struct DIR
{
         int east,south,west,north;
}mark[DEN][DEN];      //定义一个结构体,用来存储东南西北是否能通过

int tmp[DEN][DEN];    //用来做标记的,看是否已经走过
int date[DEN][DEN];   //用来来存储输入的数据部分
int m,n,max;          //max用来存储最大值
int t;                //t用来计数
void sign()          //调用sign函数,用来计算东西南北四个方向能否通过
{
         int i,j;
         for(i=0;i<m;i++)
               for(j=0;j<n;j++)
               {
                      if(!(date[i][j]&1))
                              mark[i][j].west=1;//西能通过
                      if(!(date[i][j]&2))
                              mark[i][j].north=1;//北能通过
                      if(!(date[i][j]&4))
                              mark[i][j].east=1;//东能通过
                      if(!(date[i][j]&8))
                              mark[i][j].south=1;//南能通过
               }
}

void find(int i,int j)  //用find来查找连通房间
{
          if(t>max)
          max=t;
          if(mark[i][j].east==1&&tmp[i][j+1]==0)  //如果东边不是墙,并且东边的一个房间没有标记,就进入。
          {
                   tmp[i][j+1]=1;      //进入之后马上标记为已走过哦         
                   t++;                //总房间个数加一
                  find(i,j+1);        //然后进入
          }
         if(mark[i][j].south==1&&tmp[i+1][j]==0)  //同理
         {
                 tmp[i+1][j]=1;
                 t++;
                 find(i+1,j);
         }
        if(mark[i][j].west==1&&tmp[i][j-1]==0)   //同理
        {
                 tmp[i][j-1]=1;
                 t++;
                 find(i,j-1);
         }
         if(mark[i][j].north==1&&tmp[i-1][j]==0)  //同理
         {
                 tmp[i-1][j]=1;
                 t++;
                 find(i-1,j);
         }
         return ;

}

int main()
{
         int i,j,k=0;
         scanf("%d%d",&m,&n);
         for(i=0;i<m;i++)
                 for(j=0;j<n;j++)
                        scanf("%d",&date[i][j]);
         sign();          
         for(i=0;i<m;i++)
                for(j=0;j<n;j++)
               {
                       if(!tmp[i][j])  //未被标记才能进入
                       {
                             t=1;  //一进入t就应该为1了哦
                             tmp[i][j]=1;
                             find(i,j);
                             k++;   //每能调用一次,就证明一定有一个房间哦,所以要加一
                       }
               }
        printf("%d\n%d\n",k,max);//输出结果
        return 0;
}



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值