【蓝桥第七周】城市游戏

城市游戏

题目描述 Description

鲍勃是一个战略游戏编程专家。在他的新城市建设游戏游戏环境如下:一个城市建立了地区,有街道、树木,工厂和建筑物。在该地区仍然有一些空间是空置的。他游戏的战略任务是赢得尽可能多的房租钱从这些免费空间。

赢得房租钱你必须建造建筑,只能是长方形的,长和宽。鲍勃正试图找到一种方法来建造尽可能最大的在每个区域。

但他遇到一些问题——他是不允许破坏已经存在的建筑、树木、工厂和街道建筑。

每个地区都有其宽度和长度。平等广场的区域划分为网格单元。租金支付您正在构建的每个单元站是3美元。

你的任务是帮助鲍勃解决这个问题。整个城市分为K地区。

每一个长方形的区域是有自己不同的网格大小与长度宽度M和N。现有的占领,单位是标明符号R ,空置单位标记符号F。

输入描述 Input Description

输入一行包含区域描述。

定义了一个描述在以下方式:第一行包含两个数,长度M < = 1000和宽度N < = 1000,由一个空格分开

下M行包含N个符号,标志着保留或自由网格单元,由一个空格分开。使用的符号是:

R -保留单位

F -免费的单位

输出描述 Output Description

为每个数据集在输入打印在单独的行中,在标准输出,整数表示装配获得的利润最大的建筑区域编码的数据集。

样例输入 Sample Input

5 6

R F F F F F

F F F F F F

R R R F F F

F F F F F F

F F F F F F

样例输出 Sample Output

45

[解题思路]

     可以把R替换成0,F替换成1,即看成求最大子矩阵的问题,而这里将用另一种方法求解。即在一个0-1矩阵里面找出最大一个全1子矩阵。用二维数组来存放矩阵,从matrix[1][1]到matrix[i][j]遍历,由于,找一个最大的全1矩阵,即找出全1矩阵的最大面积,面积可以用h[j]*(r[j]-l[j]+1)表示,其中h[j]为最大高度,r[j]为最右的位置,l[j]为最左位置,所以(r[j]-l[j]+1)为最大宽度。

[代码实现]

/*最大全1子矩阵问题*/
#include<iostream>
using namespace std;
int matrix[1005][1005];
char cmatrix[1005][1005];
int h[1005];
int r[1005];
int l[1005];
int n,m,ans;
void GetMax(int n,int m)
{
	int i,j,k;
	for(i=1;i<=n;i++)
	{
		for(j=1;j<=m;j++)
		{
				if(matrix[i][j]==1)
					h[j]++;
				else
					h[j]=0;
		}
		h[0]=h[m+1]=-1;
		for(j=1;j<=m;j++)   //l[i]表示h[i]左边最远的一个h值不小于h[i]的位置
		{             //即l[i]到i的所有h值均>=h[i],r[i]同理
			k=j;
			while(h[j]<=h[k-1]) k=l[k-1];
			l[j]=k;
		}
		for(j=m;j>=1;j--)    //r[i]表示h[i]右边最远的一个h值不小于h[i]的位置
		{
			k=j;
			while(h[j]<=h[k+1]) k=r[k+1];
			r[j]=k;
		}
		for(j=1;j<=m;j++)
		{
			if(ans<h[j]*(r[j]-l[j]+1))  ans=h[j]*(r[j]-l[j]+1);
		}
	}
}
void Input()
{
	cin>>n>>m;
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=m;j++)
		{
			cin>>cmatrix[i][j];
		}
	}
}
void TransForm()
{
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
			if(cmatrix[i][j] == 'F')  
				matrix[i][j]=1;	
		
}
int main(int argc,char *argv[])
{
	Input();
	TransForm();
	GetMax(n,m);
	cout<<ans*3<<endl;
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值