第三次题组 [Cloned] - Virtual Judge (vjudge.net)
【题目描述】
鲍勃想在他的办公室里放一张新的谈判桌。为此,他彻底测量了办公室并绘制了平面图:鲍勃的办公室是一n*m的矩形房间。房间的每一平方米要么被一些家具占据,要么空闲。谈判桌是长方形的,应该放置,其侧面与办公室墙壁平行。鲍勃不想改变或重新排列任何东西,这就是为什么桌子将占据的所有方块最初都应该是空闲的。Bob 希望新桌子能容纳尽可能多的人,因此它的周长应该是最大的。帮助鲍勃找出他办公室谈判桌的最大可能周长。
【输入】
第一行包含 2 个空格分隔的数字 n 和 m(1 ≤ n、m ≤ 25) — 办公室尺寸。 然后是 n 行,每行 m 个字符 0 或 1。0 代表一平方米的办公室。1 代表占用的平方米。保证房间里至少有一平方米是空闲的。
【输出】
输出一个数字 — 鲍勃办公室谈判桌的最大可能周长。
解题思路
这个题目首先要注意的是:计算周长的方法,例如:一块1*1大小的谈判桌,它的周长是4.
题意大概是:要求矩形的最大周长是多少,矩形中间也不能包含被占用的‘1’。(刚开始这里理解错了,所以一直没看懂题目)
遍历行和列,如果当前的位置是空闲的‘0’,计算以该位置为左上顶点的矩形的最大周长(用Solve函数实现)。
其中Solve函数的思路是:从该位置向下找和向左找(两层循环),内层循环时向左找,外层循环向下找,要保证行和列尽可能大,每层循环得到一个计算出的临时周长max,将该值max与ans比较,如果sum>ans,就将ans赋值为sum,如此循环来获取最大周长。
代码如下
#include<stdio.h>
char a[30][30];
int n, m;
//从上至下,找以该点为左上角顶点的矩形
int Solve(int x, int y) {
int mint = 30;//mint记录遍历时,i对应的行上面的‘0’的长度,不会超过25
int ans=0;//ans是找到的最大值,函数将要返回的值
int i, j;
for (i = x; i < n; i++) {
for (j = y; j < m; j++) {//找行上面的‘0’的长度
if (a[i][j] == '1')
break;
}
int len;//以(x,y)为左上顶点的,列的长度
if (j != y) {
len = i - x + 1;
}
//如果j==y说明没有长度,没有长度的情况宽度也不用计算了
else
break;
//如果之前的最短长度大于当前的长度,就将mint替换
if (mint > j - y) {
mint = j - y;
}
//周长是(当前的最短长度+宽度)*2
int max = (mint + len) * 2;
if (max > ans) {
ans = max;
}
}
return ans;
}
int main() {
scanf("%d%d", &n, &m);
int maxt = 0;
for (int i = 0; i < n; i++) {
scanf("%s", a[i]);
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
//当位置为空时,进入函数,统计以当前点为左上角顶点的最大周长
if (a[i][j] == '0') {
int t = Solve(i, j);
if (t > maxt) {
maxt = t;
}
}
}
}
printf("%d", maxt);
}