JZOJ 5111. 【usaco2017_Mar Platinum】Modern Art

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

  • 这提示一道英文题,光看懂题就用了就用了不少时间。

  • 题目大意是在一个 NN 的矩阵中,不断加入一个个大小不同、颜色不同的矩阵,(颜色共 NN 种),且后加入的矩阵会覆盖之前的矩阵,

  • 现给出全加入后的最终结果,问哪种颜色的矩阵可能先加入,求满足的颜色数。

  • 我们对每个点进行讨论,求出每个点被多少个矩阵覆盖。

  • 怎么求呢?——用矩阵前缀和!对于一个矩阵:

Solution

  • 之后做一遍矩阵前缀和即可!

  • 对于一个点,如果该点前缀和的值 >1 ,说明被多个矩阵覆盖,则这个点的颜色不可行。

  • 这样把所有不可行的点的颜色都标记后,剩下的颜色就是可行的了,统计答案即可。

  • 特殊情况:全矩阵只有一种颜色,则该颜色不会是最早的,此时答案为: N21

  • 时空复杂度都为 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;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值