Codeforces Round #688 (Div. 2) C. Triangles(思維,數學)

無愧於人發表於2020-12-05

題目傳送
題意:
給你一個n*n的矩陣,上面寫著0到9的數字,現在問你:選取同一種數字中的任意三個,組成的三角形的最大面積 * 2是多少,每選取一種數字的時候,你最多可以改動一次,使得某個位置變成你想要的數字,在這個數字選取完後,改動的數字變回原樣。

思路:
1.既然每次可以改一次,那麼肯定只要存在倆個點那麼三角形面積就不會為0.那麼我直接列舉倆個點就是了,另外一個點配合選取的倆個點使得面積最大即可,但是暴力選取倆個點會T

2.我們知道三角形面積是 底乘高除二 ,那麼既然另外一個點是我們可以控制的,可以配合倆個點達到面積最大值。那麼這個倆個點我們要選取的話,什麼情況下,他們可能存在最大值。

3.那麼我們只需要控制這個三角形的高,然後底我們可以列舉每一個點,再控制另外一個點取最大的底。那麼這個高怎麼選呢?因為這個三角形的一邊必須平行矩形的一邊,所以我們先假設這個高平行x軸,那麼我們肯定是選x最大和最小的倆個點去列舉,因為在列舉的時候,高 能達到最大值。同理假設這個高平行y軸,那麼我們肯定是選y最大和最小的倆個點去列舉, 這樣列舉一遍,取最大值即可

#include<bits/stdc++.h>
using namespace std;
const int N = 4e6 + 100;
char str[2005][2005];
signed main()
{
    std::ios::sync_with_stdio(false);
    cin.tie(0),cout.tie(0);
    //    freopen("input.txt","r",stdin);
    //    freopen("output.txt","w",stdout);
    int t;
    cin >> t;
    while(t--)
    {
        int n;
        cin >> n;
        for(int i = 1;i <= n;i++)
            for(int j = 1;j <= n;j++)
                cin >> str[i][j];
        for(int num = 0;num < 10;num++)
        {
            int x = 0,y = 0,Max = 0,m = 0,xx = 0,yy = 0,xxx = INF,yyy = INF,xxxx = INF,yyyy = INF;
            for(int i = 1;i <= n;i++)
            {
                for(int j = 1;j <= n;j++)
                {
                    if(str[i][j] - '0' == num)
                    {
                        if(x < i)//x最大的點
                            x = i,y = j;
                            
                        if(yy < j)//y最大的點
                            xx = i,yy = j;
                            
                        if(xxx > i)//x最小的點
                            xxx = i,yyy = j;
                            
                        if(yyyy > j)//y最小的點
                            yyyy = j,xxxx = i;
                            
                        m++;
                    }
                }
            }
            if(m < 2) {cout << 0 << " ";continue;}//如果都沒有倆個點,面積為0
            for(int i = 1;i <= n;i++)//列舉每一個點
            {
                for(int j = 1;j <= n;j++)
                {
                    if(str[i][j] - '0' == num)
                    {
                        Max = max(Max,max(n-j,j-1)*(x-i));//另外一點任意取,所以在高固定的情況下,取最大的底
                        Max = max(Max,max(n-y,y-1)*(x-i));

                        Max = max(Max,max(n-i,i-1)*(yy-j));//上底
                        Max = max(Max,max(n-xx,xx-1)*(yy-j));//下底

                        Max = max(Max,max(n-j,j-1)*(i-xxx));
                        Max = max(Max,max(n-yyy,yyy-1)*(i-xxx));

                        Max = max(Max,max(n-i,i-1)*(j-yyyy));
                        Max = max(Max,max(n-xxxx,xxxx-1)*(j-yyyy));
                    }
                }
            }
            cout << Max << " ";
        }
        cout << endl;
    }
}

相關文章