| ||||||||||
| Online Judge | Problem Set | Authors | Online Contests | User | ||||||
|---|---|---|---|---|---|---|---|---|---|---|
| Web Board Home Page F.A.Qs Statistical Charts | Current Contest Past Contests Scheduled Contests Award Contest | |||||||||
雁过留声——扫描+增量我的方法比较土鳖,但绝对管用。
先考虑对于一个颜色,如何有多少个cross
我的方法:记录每个格子向上、下、左、右各有多少个格子颜色与它相同,然后
取最小-1,就是以这个格子为中心的cross个数了。最后,统统相加。
由于颜色数≤100,所以我把颜色分开考虑,存储100个统计信息。
那么如何应对修改呢?
最朴素的想法:重新扫描、统计。其实,可以利用一下修改前的信息的:
不与被修改的格子同行、同列的格子的信息可以保留,
只有被覆盖的颜色和新的颜色的信息需要更新。
然后就是写了。为了不让代码过长,其实有一些技巧的。
关键代码:
void updataL(int c,int i){
for (int j=0;j<M;j++)
if (color[i][j]!=c+1)lc[c][i][j]=0;
else if (!j || color[i][j-1]!=c+1)lc[c][i][j]=1;
else lc[c][i][j]=lc[c][i][j-1]+1;
for (int j=M-1;j>=0;j--)
if (color[i][j]!=c+1)rc[c][i][j]=0;
else if (j==M-1 || color[i][j+1]!=c+1)rc[c][i][j]=1;
else rc[c][i][j]=rc[c][i][j+1]+1;
}
void updataL_nc(int c,int i){
int tmp;
for (int j=0;j<M;j++)
if (color[i][j]==c+1){
tmp=uc[c][i][j];
if (tmp>lc[c][i][j])tmp=lc[c][i][j];
if (tmp>rc[c][i][j])tmp=rc[c][i][j];
if (tmp>dc[c][i][j])tmp=dc[c][i][j];
if (nc[c][i][j]!=tmp-1){
cnt[c]+=tmp-1-nc[c][i][j];
nc[c][i][j]=tmp-1;
}
}else cnt[c]-=nc[c][i][j],nc[c][i][j]=0;
}
void updataR(int c,int j){
for (int i=0;i<N;i++)
if (color[i][j]!=c+1)uc[c][i][j]=0;
else if (!i || color[i-1][j]!=c+1)uc[c][i][j]=1;
else uc[c][i][j]=uc[c][i-1][j]+1;
for (int i=N-1;i>=0;i--)
if (color[i][j]!=c+1)dc[c][i][j]=0;
else if (i==N-1 || color[i+1][j]!=c+1)dc[c][i][j]=1;
else dc[c][i][j]=dc[c][i+1][j]+1;
}
void updataR_nc(int c,int j){
int tmp;
for (int i=0;i<N;i++)
if (color[i][j]==c+1){
tmp=uc[c][i][j];
if (tmp>lc[c][i][j])tmp=lc[c][i][j];
if (tmp>rc[c][i][j])tmp=rc[c][i][j];
if (tmp>dc[c][i][j])tmp=dc[c][i][j];
if (nc[c][i][j]!=tmp-1){
cnt[c]+=tmp-1-nc[c][i][j];
nc[c][i][j]=tmp-1;
}
}else cnt[c]-=nc[c][i][j],nc[c][i][j]=0;
}
for (int i=0;i<N;i++)for (int j=0;j<M;j++)scanf("%d",&color[i][j]);
for (int i=0;i<C;i++)
for (int j=0;j<N;j++)
for (int k=0;k<M;k++)
nc[i][j][k]=0;
for (int i=0;i<C;i++)cnt[i]=0;
for (int i=0;i<C;i++)
for (int j=0;j<N;j++)
updataL(i,j);
for (int i=0;i<C;i++)
for (int j=0;j<M;j++)
updataR(i,j);
for (int i=0;i<C;i++)
for (int j=0;j<N;j++)
updataL_nc(i,j);
while (Q--){
scanf("%s",buf);
if (buf[0]=='Q'){
scanf("%d",&x);
printf("%d\n",cnt[x-1]);
}else{
scanf("%d %d %d",&x,&y,&c);x--;y--;
d=color[x][y];
color[x][y]=c;
updataL(d-1,x);updataR(d-1,y);
updataL_nc(d-1,x);updataR_nc(d-1,y);
updataL(c-1,x);updataR(c-1,y);
updataL_nc(c-1,x);updataR_nc(c-1,y);
}
}
Followed by: Post your reply here: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator