Description
Art critics worldwide have only recently begun to recognize the creative genius behind the great bovine painter, Picowso.
Picowso paints in a very particular way. She starts with an N×Nblank canvas, represented by an N×N grid of zeros, where a zero indicates an empty cell of the canvas. She then draws N^2 rectangles on the canvas, one in each of N^2 colors (conveniently numbered 1…N^2). For example, she might start by painting a rectangle in color 2, giving this intermediate canvas:
2 2 2 0
2 2 2 0
2 2 2 0
0 0 0 0
She might then paint a rectangle in color 7:
2 2 2 0
2 7 7 7
2 7 7 7
0 0 0 0
And then she might paint a small rectangle in color 3:
2 2 3 0
2 7 3 7
2 7 7 7
0 0 0 0
Each rectangle has sides parallel to the edges of the canvas, and a rectangle could be as large as the entire canvas or as small as a single cell. Each color from 1…N^2 is used exactly once, although later colors might completely cover up some of the earlier colors.
Given the final state of the canvas, please count how many of the N^2 colors could have possibly been the first to be painted.
Input
The first line of input contains N, the size of the canvas (1≤N≤1000). The next N lines describe the final picture of the canvas, each containing N integers that are in the range 0…N^2. The input is guaranteed to have been drawn as described above, by painting successive rectangles in different colors.
Output
Please output a count of the number of colors that could have been drawn first.
Sample Input
4
2 2 3 0
2 7 3 7
2 7 7 7
0 0 0 0
Sample Output
14
Hint
In this example, color 2 could have been the first to be painted. Color 3 clearly had to have been painted after color 7, and color 7 clearly had to have been painted after color 2. Since we don’t see the other colors, we deduce that they also could have been painted first.
Solution
这提示一道英文题,光看懂题就用了就用了不少时间。
题目大意是在一个 N∗N 的矩阵中,不断加入一个个大小不同、颜色不同的矩阵,(颜色共 N∗N 种),且后加入的矩阵会覆盖之前的矩阵,
现给出全加入后的最终结果,问哪种颜色的矩阵可能先加入,求满足的颜色数。
我们对每个点进行讨论,求出每个点被多少个矩阵覆盖。
怎么求呢?——用矩阵前缀和!对于一个矩阵:
之后做一遍矩阵前缀和即可!
对于一个点,如果该点前缀和的值 >1 ,说明被多个矩阵覆盖,则这个点的颜色不可行。
这样把所有不可行的点的颜色都标记后,剩下的颜色就是可行的了,统计答案即可。
特殊情况:全矩阵只有一种颜色,则该颜色不会是最早的,此时答案为: N2−1
时空复杂度都为 O(N2) 。
Code
#include<cstdio>
using namespace std;
const int N=1002;
struct data
{
int sx,sy,tx,ty;
}a[N*N];
int n,bz1;
int map[N][N],f[N][N];
bool ans[N*N];
bool bz;
inline int read()
{
int X=0; char ch=0;
while(ch<'0' || ch>'9') ch=getchar();
while(ch>='0' && ch<='9') X=(X<<3)+(X<<1)+ch-'0',ch=getchar();
return X;
}
int main()
{
n=read();
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
map[i][j]=read();
if(map[i][j])
{
if(bz1 && bz1!=map[i][j]) bz=true; else bz1=map[i][j];
if(!a[map[i][j]].sx || i<a[map[i][j]].sx) a[map[i][j]].sx=i;
if(!a[map[i][j]].sy || j<a[map[i][j]].sy) a[map[i][j]].sy=j;
if(i>a[map[i][j]].tx) a[map[i][j]].tx=i;
if(j>a[map[i][j]].ty) a[map[i][j]].ty=j;
}
}
if(!bz)
{
printf("%d",n*n-1);
return 0;
}
for(int i=n*n;i;i--)
if(a[i].tx)
{
f[a[i].sx][a[i].sy]++;
f[a[i].tx+1][a[i].ty+1]++;
f[a[i].sx][a[i].ty+1]--;
f[a[i].tx+1][a[i].sy]--;
}
int sum=n*n;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
f[i][j]+=f[i-1][j]+f[i][j-1]-f[i-1][j-1];
if(f[i][j]>1)
{
if(!ans[map[i][j]]) sum--;
ans[map[i][j]]=true;
}
}
printf("%d",sum);
return 0;
}