Codeforces Round #688 (Div. 2) C. Triangles(枚举)

题目链接:https://codeforc.es/contest/1453/problem/C

Gildong has a square board consisting of n rows and n columns of square cells, each consisting of a single digit (from 0 to 9). The cell at the j-th column of the i-th row can be represented as (i,j), and the length of the side of each cell is 1. Gildong likes big things, so for each digit d, he wants to find a triangle such that:

Each vertex of the triangle is in the center of a cell.
The digit of every vertex of the triangle is d.
At least one side of the triangle is parallel to one of the sides of the board. You may assume that a side of length 0 is parallel to both sides of the board.
The area of the triangle is maximized.
Of course, he can’t just be happy with finding these triangles as is. Therefore, for each digit d, he’s going to change the digit of exactly one cell of the board to d, then find such a triangle. He changes it back to its original digit after he is done with each digit. Find the maximum area of the triangle he can make for each digit.

Note that he can put multiple vertices of the triangle on the same cell, and the triangle can be a degenerate triangle; i.e. the area of the triangle can be 0. Also, note that he is allowed to change the digit of a cell from d to d.

Input
Each test contains one or more test cases. The first line contains the number of test cases t (1≤t≤1000).

The first line of each test case contains one integer n (1≤n≤2000) — the number of rows and columns of the board.

The next n lines of each test case each contain a string of n digits without spaces. The j-th digit of the i-th line is the digit of the cell at (i,j). Each digit is one of the characters from 0 to 9.

It is guaranteed that the sum of n2 in all test cases doesn’t exceed 4⋅106.

Output
For each test case, print one line with 10 integers. The i-th integer is the maximum area of triangle Gildong can make when d=i−1, multiplied by 2.

Example

input

5
3
000
122
001
2
57
75
4
0123
4012
3401
2340
1
9
8
42987101
98289412
38949562
87599023
92834718
83917348
19823743
38947912

output

4 4 1 0 0 0 0 0 0 0
0 0 0 0 0 1 0 1 0 0
9 6 9 9 6 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
18 49 49 49 49 15 0 30 42 42

分析

我们可以发现,每个数字最大的三角形面积的三角形肯定在以最左边和最右边的两排该数字中取两个连成的一边上,也就是在每行的最左边的该数字和左右边的该数字(如果出现过)。
就将每行最左边和最右边的该数字的点加入集合,再枚举集合的所有可能边找最大面积。

代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

int T;
int n;
char a[2007][2007],b[2007][2007],vis[2007][2007];
int sum[10],res[10];
int cnt;
vector<pair<ll, ll> > v[11];

int cal(int x1,int y1,int x2,int y2)
{
	int maxx = 0;
	if(x1 == x2)
	{
		maxx = max(maxx, abs(y1 - y2) * (x1 - 1));
		maxx = max(maxx, abs(y1 - y2) * (n - x1));
	}
	else if(y1 == y2)
	{
		maxx = max(maxx, abs(x1 - x2) * (y1 - 1));
		maxx = max(maxx, abs(x1 - x2) * (n - y1));
	}
	else
	{
		maxx = max(maxx, abs(x1 - x2) * (y1 - 1));
		maxx = max(maxx, abs(x1 - x2) * (n - y1));
		maxx = max(maxx, abs(x1 - x2) * (y2 - 1));
		maxx = max(maxx, abs(x1 - x2) * (n - y2));
		maxx = max(maxx, abs(y1 - y2) * (x1 - 1));
		maxx = max(maxx, abs(y1 - y2) * (n - x1));
		maxx = max(maxx, abs(y1 - y2) * (x2 - 1));
		maxx = max(maxx, abs(y1 - y2) * (n - x2));
	}
	return maxx;
}

void Cal(int d)
{
	for(int i=0;i<v[d].size();i++)
		for(int j=i+1;j<v[d].size();j++)
		{
			res[d] = max(res[d], cal(v[d][i].first, v[d][i].second, v[d][j].first, v[d][j].second));
		}
}

void solve()
{
	cnt = 0;
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
    		vis[i][j] = 0;
	}
	for(int i=0;i<10;i++) v[i].clear();
    
	for(int z=0;z<10;z++)
	{
		cnt = 0;
		if(sum[z] < 2)
		{
			res[z] = 0;
			continue;
		}
		int p[2007][2] = {0};
		for(int i=1;i<=n;i++)
			for(int j=1;j<=n;j++)
			{
				int x = a[i][j] - '0';
				if(x == z)
				{
					vis[i][j] = 1;
					break;
				}
			}
		for(int i=1;i<=n;i++)
			for(int j=n;j>=1;j--)
			{
				int x = a[i][j] - '0';
				if(x == z)
				{
					vis[i][j] = 1;
					break;
				}
			}
		for(int i=n;i>=1;i--)
			for(int j=1;j<=n;j++)
			{
				int x = a[i][j] - '0';
				if(x == z)
				{
					vis[i][j] = 1;
					break;
				}
			}
		for(int i=n;i>=1;i--)
			for(int j=n;j>=1;j--)
			{
				int x = a[i][j] - '0';
				if(x == z)
				{
					vis[i][j] = 1;
					break;
				}
			}
		
	}
	for(int i=1;i<=n;i++)
			for(int j=1;j<=n;j++)
				if(vis[i][j] == 1)
				{
					v[a[i][j] - '0'].push_back(make_pair(i, j));
				}
	for(int d = 0; d <= 9; d++) {
        Cal(d);
    }
    
}

int main()
{
	T = 1;
	scanf("%d",&T);
	while(T--)
	{
		memset(sum, 0, sizeof(sum));
		memset(res, 0, sizeof(res));
		scanf("%d",&n);
		for(int i=1;i<=n;i++)
			scanf("%s",a[i]+1);
		for(int i=1;i<=n;i++)
			for(int j=1;j<=n;j++)
			{
				int x = a[i][j] - '0';
				sum[x]++;
			}
		
		solve();
		for(int i=0;i<10;i++) printf("%d ",res[i]);
		printf("\n");
	}
	return 0;
}
已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 像素格子 设计师:CSDN官方博客 返回首页