JZOJ.【USACO 2017 US Open Platinum】Problem 1 Modern Art题解
思路:
有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); }