CF1453C Solution

题目链接

题解

为了计算面积,需将三角形中与网格平行的边作为三角形的底。显然底越长面积越大,因此对于点\(A\),可以将满足\(AB\)与网格平行且距离最长的\(B\)的数值改为与\(A\)一样。而另一个顶点为满足高最长,一定是\(d\)数值可以到达的最上、最下、最左或最右的格点,预处理即可。

AC代码

#include<bits/stdc++.h>
using namespace std;
const int N=2010;
char mp[N][N];
int d[N][N],pos[20][10],ans[20];
//pos[i][j]:数值为i的格点最上(0)下(1)左(2)右(3)的行/列号
int main()
{
	int t,n;
	scanf("%d",&t);
	while(t--)
	{
		memset(pos,-1,sizeof(pos));
		memset(ans,0,sizeof(ans));
		scanf("%d",&n);
		for(int i=1;i<=n;i++) scanf("%s",mp[i]+1);
		for(int i=1;i<=n;i++)
			for(int j=1;j<=n;j++) d[i][j]=mp[i][j]-'0';
        //预处理pos数组
		for(int i=1;i<=n;i++)
		{
			for(int j=1;j<=n;j++)
			{
				int tmp=d[i][j];
				if(pos[tmp][0]>i || pos[tmp][0]==-1) pos[tmp][0]=i;
				if(pos[tmp][1]<i) pos[tmp][1]=i;
				if(pos[tmp][2]>j || pos[tmp][2]==-1) pos[tmp][2]=j;
				if(pos[tmp][3]<j) pos[tmp][3]=j;
			}
		}
        //枚举前文中的点A,统计答案
		for(int i=1;i<=n;i++)
		{
			for(int j=1;j<=n;j++)
			{
				int tmp=d[i][j];
				ans[tmp]=max(ans[tmp],max(n-i,i-1)*(pos[tmp][3]-j));
				ans[tmp]=max(ans[tmp],max(n-i,i-1)*(j-pos[tmp][2]));
				ans[tmp]=max(ans[tmp],max(n-j,j-1)*(pos[tmp][1]-i));
				ans[tmp]=max(ans[tmp],max(n-j,j-1)*(i-pos[tmp][0]));
			}
		}
		for(int i=0;i<10;i++) printf("%d ",ans[i]);
		printf("\n");
	}
	return 0;
}
上一篇:【CF1473E】Minimum Path


下一篇:Pupils Redistribution