D - Bargaining Table

第三次题组 [Cloned] - Virtual Judge (vjudge.net)

【题目描述】

鲍勃想在他的办公室里放一张新的谈判桌。为此,他彻底测量了办公室并绘制了平面图:鲍勃的办公室是一n*m的矩形房间。房间的每一平方米要么被一些家具占据,要么空闲。谈判桌是长方形的,应该放置,其侧面与办公室墙壁平行。鲍勃不想改变或重新排列任何东西,这就是为什么桌子将占据的所有方块最初都应该是空闲的。Bob 希望新桌子能容纳尽可能多的人,因此它的周长应该是最大的。帮助鲍勃找出他办公室谈判桌的最大可能周长。

【输入】

第一行包含 2 个空格分隔的数字 n 和 m(1 ≤ nm ≤ 25) — 办公室尺寸。 然后是 n 行,每行 m 个字符 0 或 1。0 代表一平方米的办公室。1 代表占用的平方米。保证房间里至少有一平方米是空闲的。

【输出】

输出一个数字 — 鲍勃办公室谈判桌的最大可能周长。

解题思路

这个题目首先要注意的是:计算周长的方法,例如:一块1*1大小的谈判桌,它的周长是4.

题意大概是:要求矩形的最大周长是多少,矩形中间也不能包含被占用的‘1’。(刚开始这里理解错了,所以一直没看懂题目)

遍历行和列,如果当前的位置是空闲的‘0’,计算以该位置为左上顶点的矩形的最大周长(用Solve函数实现)。

其中Solve函数的思路是:从该位置向下找和向左找(两层循环),内层循环时向左找,外层循环向下找,要保证行和列尽可能大,每层循环得到一个计算出的临时周长max,将该值max与ans比较,如果sum>ans,就将ans赋值为sum,如此循环来获取最大周长。

代码如下

#include
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);
}

你可能感兴趣的:(题组,学习,算法)