思路:
有N^2种颜色,故ANS初值为N^2
求每种颜色的上下左右界限,以此得到左上角、右下角坐标
暴力枚举每种颜色区间,寻找其中的不同颜色(重叠),每当发现一种ANS-1
记得要标记每种颜色有没有重叠,每种颜色只能算一次
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
using namespace std;
int ans,n,a[1005][1005],cnt,ber[1000005][2],b[1000005];
bool bz=1;
struct node
{
int u,d,l,r,c;
}c[1000005];
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
scanf("%d",&a[i][j]);
int col=a[i][j];
if(col==0)continue;
if(ber[col][0]==0)
{
ber[col][0]=1;
ber[col][1]=++cnt;
c[cnt].c=col;
c[cnt].u=1000000000;
c[cnt].l=1000000000;
}
c[ber[col][1]].u=min(i,c[ber[col][1]].u);
c[ber[col][1]].d=max(i,c[ber[col][1]].d);
c[ber[col][1]].l=min(j,c[ber[col][1]].l);
c[ber[col][1]].r=max(j,c[ber[col][1]].r);
}
}
ans=n*n;
for(int i=1;i<=cnt;i++)
{
for(int x=c[i].u;x<=c[i].d;x++)
{
for(int y=c[i].l;y<=c[i].r;y++)
{
if(a[x][y]!=c[i].c&&b[a[x][y]]==0)
{
ans--;
bz=0;
b[a[x][y]]=1;
}
}
}
}
if(cnt==1)ans=n*n-1;
else
{
if(bz)
{
ans=n*n;
}
}
printf("%d\n",ans);
}