CF1453C 三角形

1 CF1453C 三角形

2 题目描述

Gildong有一个正方形板,由\(𝑛\)行和\(𝑛\)列的正方形单元组成,每个单元由一个一位数(从 \(0\)\(9\))组成。\(𝑖\)\(𝑗\) 列处的单元格可表示为 \((𝑖,𝑗)\),每个单元格的边长为 \(1\)。Gildong喜欢大的东西,所以对于每一个数字 \(𝑑\),他想找到一个这样的三角形:
三角形的每个顶点都在一个单元格的中心。
三角形的每个顶点的数字都是 \(𝑑\)
三角形的至少一侧与板的一侧平行。可以假设长度为 \(0\) 的一侧与板的两侧平行。
三角形的面积最大。
当然,他不能只对找到这些三角形感到高兴。因此,对于每个数字 \(𝑑\),他将把板的一个单元格的数字改为 \(𝑑\),然后找到这样的三角形。他在处理完每个数字后把它改回原来的数字。求他能为每个数字所做的三角形的最大面积。
注意,他可以把三角形的多个顶点放在同一个单元格上,三角形可以是简并三角形;即。 三角形的面积可以是\(0\)。此外,注意他可以将单元格的数字从 \(𝑑\) 更改为 \(𝑑\)

3 解题思路

分析性质,我们发现,算出的最终值肯定有一个节点是修改过的(将 \(k\) 修改成 \(k\) 也可以)。从这一点出发,我们可以想到:对于任意一个已经确定的节点,在其所在的行或者列的四个极端(最上,最下,最左,最右)确定第二个节点,并取这个节点与这四个节点在水平方向长度的最大值,作为底,并找到相反方向的最长的长度作为高(比如选择了最左,那就找当前列最上和最下哪一个离当前节点最远并作为高。这时假设当前节点的坐标为 \((x, y)\),最上、最下的节点距离这个节点的距离最大为 \(m\),那么此时答案的值就是 \((y-1) * m\))。

这样我们就能确定出以每一个节点为顶点之一的最大面积,之后枚举每一个存在的节点计算面积即可(这里的节点意为在寻找以 \(k\) 为顶点的最大面积时值为 \(k\) 的点)。

4 代码(空格警告):

#include <iostream>
#include <queue>
#include <cstring>
#include <cstdio>
using namespace std;
const int N = 2005;
int T, n, x, y, digit;
char digi;
queue< pair<int, int> > q[10];
int lg[10], rg[10], ug[10], dg[10];
int ans[10];
int main()
{
    scanf("%d", &T);
    while (T--)
    {
        memset(lg, 0x3f, sizeof(lg));
        memset(rg, 0, sizeof(rg));
        memset(ug, 0x3f, sizeof(ug));
        memset(dg, 0, sizeof(dg));
        memset(ans, 0, sizeof(ans));
        scanf("%d", &n);
        for (int i = 1; i <= n; i++)
        {
            for (int j = 1; j <= n; j++)
            {
                cin >> digi;
                digit = (digi - '0');
                q[digit].push(make_pair(i, j));
                lg[digit] = min(lg[digit], j);
                rg[digit] = max(rg[digit], j);
                ug[digit] = min(ug[digit], i);
                dg[digit] = max(dg[digit], i);
            }
        }
        for (int i = 0; i <= 9; i++)
        {
            while (q[i].size())
            {
                x = q[i].front().first;
                y = q[i].front().second;
                ans[i] = max(ans[i], max(y-1, n-y) * max(x - ug[i], dg[i] - x));
                ans[i] = max(ans[i], max(x-1, n-x) * max(y - lg[i], rg[i] - y));
                q[i].pop();
            }
        }
        for (int i = 0; i <= 9; i++) printf("%d ", ans[i]);
        puts("");
    }
    return 0;
}

欢迎关注我的公众号:智子笔记

posted @ 2021-02-04 23:17  David24  阅读(67)  评论(0编辑  收藏  举报