Codeforces Round #688 (Div. 2) C
作者:互联网
Codeforces Round #688 (Div. 2) C
大意
略...
思维
艹,比赛时假了一个 \(\Theta(n^4)\) 做法,以为是 \(\Theta(n^2)\) ,调到天荒地老。
有 \(n^2\) 个点,我们需要 \(\Theta(n^2)\) 做法。
假设当前枚举到的点 \(a\) 的值是 \(d\) ,若 \(d\) 的最优结果下我们选择了在 \(d\) 上方的一个点,此时讨论一下:
若该点与 \(a\) 在同一列,那么由三角形面积公式可以得知贪心选择与 \(a\) 在同一行且离 \(a\) 最远的点修改一定是最优。
若不在同一列,我们只能在与 \(a\) 同一行的点上选择,此时依旧选择最远的点。
综上,当我们考虑选择 \(a\) 上方的点时,最优结果与该点是否与 \(a\) 在同一列无关,因为选择与 \(a\) 在同一行上的某点一定能达成最优解。
容易发现,我们只想知道 \(a\) 的上方离 \(a\) 所在的行最远的且值为 \(d\) 的点。
可以很容易的将选择上方拓展到选择所有四个方向。
代码
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
using namespace std;
#define ll long long
#define ull unsigned long long
#define cint const int&
#define Pi acos(-1)
const int mod = 998244353;
const int inf_int = 0x7fffffff;
const ll inf_ll = 0x7fffffffffffffff;
const double ept = 1e-9;
int t, n;
int a[2020][2020];
int loc[5][10];
int ans[10];
// 1,3 row 2,4 column
int main() {
char tmp;
cin >> t;
while(t--) {
cin >> n;
for(int i=1; i<=n; i++)
for(int j=1; j<=n; j++) {
cin >> tmp; a[i][j] = tmp-'0';
}
memset(loc, -1, sizeof loc);
memset(ans, 0, sizeof ans);
for(int i=1; i<=n; i++)
for(int j=1; j<=n; j++)
for(int k=1; k<=4; k++) {
int r = a[i][j];
if(loc[k][r]<0) {
if(k&1) loc[k][r] = i;
else loc[k][r] = j;
} else {
if(k==2) loc[k][r] = min(loc[k][r],j);
if(k==3) loc[k][r] = max(loc[k][r],i);
if(k==4) loc[k][r] = max(loc[k][r],j);
}
}
for(int i=1; i<=n; i++)
for(int j=1; j<=n; j++) {
int r = a[i][j];
ans[r] = max(ans[r], max(j-1,n-j)*max(i-loc[1][r],loc[3][r]-i));
ans[r] = max(ans[r], max(i-1,n-i)*max(j-loc[2][r],loc[4][r]-j));
}
for(int i=0; i<=9; i++) cout << ans[i] << ' ';
cout << endl;
}
return 0;
}
补题一时爽,当场做题火葬场...
标签:const,int,Codeforces,long,选择,688,Div,include,define 来源: https://www.cnblogs.com/ullio/p/14092274.html