cf12.4
cf div.2 #668
題意
給一個數字矩陣,對於每一個數,可以任意選兩個數,加自己構造的一個點,組成三角形,問什麼情況,三角形面積 * 2最大。
(這個三角形要求,至少有一條邊平行於x軸或者y軸)
題解
這種三角形面積 * 2是 ∣ x a − x b ∣ ∗ ∣ y a − y c ∣ |x_a - x_b| * |y_a - y_c| ∣xa−xb∣∗∣ya−yc∣。
我原本考慮最角落4個點,but實現有點問題。
可以考慮每行的點,把所有 ∣ x a − x b ∣ |x_a - x_b| ∣xa−xb∣記錄下來,再找面積最大的。
仔細來說:
對於某個數,記錄橫縱座標最大最小值,
遍歷每個等於這個數的點,與橫縱座標最大最小值的點找最大三角形的底和高
//額,看程式碼理解叭
//說不明白,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;
}
}