cf12.4

rainbowsea_1發表於2020-12-14

cf div.2 #668

C題目

題意

給一個數字矩陣,對於每一個數,可以任意選兩個數,加自己構造的一個點,組成三角形,問什麼情況,三角形面積 * 2最大。

(這個三角形要求,至少有一條邊平行於x軸或者y軸)

題解

這種三角形面積 * 2是 ∣ x a − x b ∣ ∗ ∣ y a − y c ∣ |x_a - x_b| * |y_a - y_c| xaxbyayc

我原本考慮最角落4個點,but實現有點問題。

可以考慮每行的點,把所有 ∣ x a − x b ∣ |x_a - x_b| xaxb記錄下來,再找面積最大的。

仔細來說:

對於某個數,記錄橫縱座標最大最小值,

遍歷每個等於這個數的點,與橫縱座標最大最小值的點找最大三角形的底和高

//額,看程式碼理解叭

//說不明白,but思路是我沒有想到過的,重點還是發現這個問題算面積只需找到底和高

提一嘴

一串無空格的字串,無需用字元輸入

可以scanf("%1d", &mp[i][j]);

#include <bits/stdc++.h>
using namespace std;
const int MAX = 2e3 + 10;
const int INF = 1e5 + 10;
int mp[MAX][MAX];
int n;
int ans[12];
inline void solve() {
    int maxx[12], mppinx[12];
	int maxy[12], miny[12];
	fill(ans, ans + 12, 0);
	fill(maxx, maxx + 12, -1); fill(maxy, maxy + 12, -1);
	fill(minx, minx + 12, INF); fill(miny, miny + 12, INF);
    for(int i = 1; i <= n; i++) {
        for(int j = 1; j <= n; j++) {
            int d = mp[i][j];
            maxx[d] = max(maxx[d], i);
            minx[d] = min(minx[d], i);
            maxy[d] = max(maxy[d], j);
            miny[d] = min(miny[d], j);
        }
    }
	for(int i = 1; i <= n; i++) {
   		for(int j = 1; j <= n; j++) {
   			int d = mp[i][j];
   			int res = max(n - j, j - 1) * max(maxx[d] - i, i - minx[d]);
   			ans[d] = max(ans[d], res);
   			res = max(n - i, i - 1) * max(maxy[d] - j, j - miny[d]);
   			ans[d] = max(ans[d], res);
		}	
	}
}
int main() {
    int T;
    scanf("%d", &T);
    while(T--) {
        scanf("%d", &n);
        for(int i = 1; i <= n; i++) {
        	for(int j = 1; j <= n; j++) 
        		scanf("%1d", &mp[i][j]);
		}
        solve();
        for(int i = 0; i < 10; i++) {
            printf("%d ", ans[i]);
        }
        cout << endl;
    }
}