Time Limit:2s Memory Limit:64MByte
Submissions:69Solved:33
Eric has an n×mn×m matrix, consisting of integers. The rows are indexed from 11 to nn from top to bottom and the columns are indexed from 11 to mm from left to right. Let's represent the matrix element on the intersection of row ii and column jj as ai,jai,j.
For each pair of integers (x,y)(x,y), Eric needs to find the number of x×yx×y submatrices such that no two elements in the submatrix are the same.
题目大意:
给你一个N*M的矩阵,让你输出一个N*M的矩阵,输出的矩阵中,对于位子(x,y)表示的是在原矩阵中,有多少个子矩阵的大小是x*y,并且子矩阵中没有重复的元素。
思路:
1、观察到1<=ai<=100,也就是说,在一个N*M大小的矩阵中,最坏情况有1e4个元素,但是其中最多只有1e2种元素,那么肯定一点就是矩阵越大,越会出现重复的情况越多。
2、那么我们不妨直接暴力搞这个问题:
直接枚举子矩阵左界限,再枚举子矩阵的上下界限(i,j),然后一直向右扫即可(每次增加从第i行到第j行的当前列的元素).通过我们的分析可知,最多扫101个元素就一定会提前break掉。
那么其实时间复杂度根本没有自己想象的那么大。
暴力粗奇迹,过程维护解的个数即可。
Ac代码:
#include<stdio.h>
#include<string.h>
using namespace std;
int ans[150][150];
int a[150][150];
int vis[103];
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n,m;
scanf("%d%d",&n,&m);
memset(ans,0,sizeof(ans));
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
scanf("%d",&a[i][j]);
}
}
for(int l=1;l<=m;l++)
{
for(int i=1;i<=n;i++)
{
for(int j=i;j<=n;j++)
{
memset(vis,0,sizeof(vis));
for(int r=l;r<=m;r++)
{
int ok=1;
for(int z=i;z<=j;z++)
{
if(vis[a[z][r]]==0)
{
vis[a[z][r]]=1;
}
else ok=0;
}
if(ok==1)
{
ans[j-i+1][r-l+1]++;
}
else break;
}
}
}
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(j==1)
printf("%d",ans[i][j]);
else printf(" %d",ans[i][j]);
}
printf("\n");
}
}
}