牛客网 Crazy Fences

题目链接:Crazy Fences

题目大意: FJ有一个牧场,牧场中有 n ( n ≤ 500 ) n(n\leq500) n(n500) 个围栏(围栏都是水平或是竖直的)和 c c c 头牛,给出每个围栏的起始点坐标和终点坐标以及每头牛的坐标,围栏围成的封闭区域成为社区,问所有的社区中,哪个社区中有最多的牛。

题目思路: 坐标离散化,把每个围栏和牛的坐标进行离散化,然后就可以搜索处理出所有社区的牛的个数,最后统计答案,需要注意的在离散化的时候,需要对点的坐标*2以保证不会把本来相邻但不相接的边连接在一起,下面是完整代码。

题目代码:

#include<stdio.h>
#include<algorithm>
#include<string.h>
#define mxn 10000
using namespace std;
int n,m,x[mxn],y[mxn],arr[mxn],_X[mxn],_Y[mxn],vis[2550][2550],Vis[mxn];
int px[5]={0,1,0,-1,0},py[5]={0,0,-1,0,1},ans,R,C,cow[2550][2550],cnt;
char map[2550][2550];
int Read(){
	int x=0,f=1;
	char ch=getchar();
	while(ch<'0'||ch>'9') {if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return f*x;
}
int compress_x(int *X,int N){//离散化x轴
	memcpy(arr,X,sizeof(arr));
	sort(arr+1,arr+N+1);
	int _N=unique(arr+1,arr+N+1)-arr-1; 
	for(int i=1;i<=N;i++)
		_X[i]=(lower_bound(arr+1,arr+_N+1,X[i])-arr)*2;	
	return _N*2;
}
int compress_y(int *Y,int N){//离散化y轴
	memcpy(arr,Y,sizeof(arr));
	sort(arr+1,arr+N+1);
	int _N=unique(arr+1,arr+N+1)-arr-1; 
	for(int i=1;i<=N;i++)
		_Y[i]=(lower_bound(arr+1,arr+_N+1,Y[i])-arr)*2;
	return _N*2;
}
void Fill(int x1,int y1,int x2,int y2){
	if(x1==x2){
		if(y1>y2)swap(y1,y2);
		for(int i=y1;i<=y2;i++)
			map[x1][i]='#';
	}
	else{
		if(x1>x2)swap(x1,x2);
		for(int i=x1;i<=x2;i++)
			map[i][y1]='#';
	}
}
int DFS(int x0,int y0){
	for(int i=1;i<=4;i++){
		int xx=x0+px[i],yy=y0+py[i];
		if(map[xx][yy]=='#'||vis[xx][yy])continue;
		if(xx<1||xx>R||yy<1||yy>C)continue;
		vis[xx][yy]=1;
		if(map[xx][yy]=='C')
			cnt++;
		DFS(xx,yy);
	}
	return cnt;
}
int main()
{
	int cc=0;
	scanf("%d %d",&n,&m);
	for(int i=1;i<=n*2;i++){
		++cc;
		x[cc]=Read();
		y[cc]=Read();
	}
	for(int i=1;i<=m;i++){
		++cc;
		x[cc]=Read();
		y[cc]=Read();
	}
	R=compress_x(x,cc);
	C=compress_y(y,cc);
	memset(map,'.',sizeof(map));
	for(int i=1;i<=n*2;i+=2){
		int x1=_X[i],x2=_X[i+1],y1=_Y[i],y2=_Y[i+1];
		Fill(x1,y1,x2,y2);
	}
	cnt=0;
	for(int i=n*2+1;i<=m+n*2;i++){
		int x=_X[i],y=_Y[i];
		map[x][y]='C';
		cow[x][y]=++cnt;
	}
	
	for(int i=n*2+1;i<=m+n*2;i++){
		if(!Vis[cow[_X[i]][_Y[i]]]){
			vis[_X[i]][_Y[i]]=1;
			cnt=1;
			Vis[cow[_X[i]][_Y[i]]]=1;
			cnt=DFS(_X[i],_Y[i]);
			ans=max(ans,cnt);
		}
	}
	printf("%d\n",ans);
	return 0;
 } 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值