题目 题解
题面
小A是一名画家。现在有一张大小为n * m的网格图,小A用K种颜色在网格图上作画。其中第i种颜色编号为i,初始时网格图中每个格子都没有颜色,编号为0。已知每种颜色小A都会使用且只使用一次,但使用的顺序是未知的。使用一种颜色时需要选定一个连续的子矩阵,将该子矩阵涂上这种颜色。后涂的颜色会覆盖之前的颜色。现在给出小A画完后的图,问有多少种颜色可能是小A最先使用的。
题解、总结
*正解就是:处理出每个颜色的四个顶点,枚举整个颜色块,如果块内有一个不合法的颜色那么k--并标记它(避免重复减去同一种颜色的可能)。
*错误1:没睡好+起床姿势不对引发的惨案->下划线的地方全部没看到->一定要按计划做每件事,专心认真投入地做一件事;要有考试的感觉
*错误2:STL不太会,存储不了全部数据->存储数据经常考小点,要熟练
*错误3:一个比较简单的模拟因为没想清楚就开始打所以途中漏洞百出,浪费很多时间->主要也是因为状态不好,但多读题多遍理解多研究样例多出几组数据,说过多少遍呢
代码
*70分的未存储全部数据:

#include<bits/stdc++.h> #define ll long long #define For(i,l,r) for(int i=l;i<=r;i++) #define Dfor(i,r,l) for(int i=r;i>=l;i--) using namespace std; const int M=1e5+5; int n,m,k,cnt,clr[M]; bool vis[M],f[M]; struct node{ int up,don,le,ri; }col[M]; inline ll read(){ ll f=1,sum=0; char ch=getchar(); while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();} while(isdigit(ch)){sum=(sum<<1)+(sum<<3)+(ch^48);ch=getchar();} return f*sum; } int main(){ freopen("paint.in","r",stdin); freopen("paint.out","w",stdout); n=read(),m=read(),k=read(); ll a[n+10][m+10]; if(n==1&&m==1){ cout<<k-1<<endl;return 0; } memset(a,0,sizeof(a)); For(i,1,k) col[i].up=1e9,col[i].le=1e9; For(i,1,n){ For(j,1,m){ a[i][j]=read(); int colo=a[i][j]; col[colo].up=min(col[colo].up,i); col[colo].don=max(col[colo].don,i); col[colo].le=min(col[colo].le,j); col[colo].ri=max(col[colo].ri,j); if(!f[colo]) clr[++cnt]=colo,f[colo]=1; } } vis[0]=1; For(i,1,cnt){ int j=clr[i]; if(!j)continue; For(p,col[j].up,col[j].don){ For(q,col[j].le,col[j].ri){ if(!vis[a[p][q]]&&a[p][q]!=j){ vis[a[p][q]]=1; k--; } } } } printf("%d ",k); return 0; }
*100分:
题面
题解、反思
代码
题面
题解、反思
代码