题意:给出一个n*m的矩阵(n<=200,m<=50000)和9种颜色,以及如下4种操作:1.将矩阵中的一块圆形区域 (x - xc)2 + (y - yc)2 ≤ r2 全涂成颜色 c。2.将矩阵中的一块菱形区域 abs(x - xc) + abs(y - yc) ≤ r 全涂成颜色 c。3.将矩阵中的一块矩形区域 xc ≤ x ≤ xc+l-1, yc ≤ y ≤ yc+w-1 全涂成颜色 c。4.将矩阵中的一块三角形区域全涂成颜色c。问最后这每种颜色的格子数。
倒着处理所有的操作,将所有染色的格子删除,用并查集类似路径压缩的方法去快速寻找下一个没有染色的格子。
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> using namespace std; const int N=201; const int M=50005; int n,m,q; char str[55]; struct node { int type,cnt,data[5]; void input() { scanf("%s",str); if(strcmp(str,"Circle")==0) cnt=4,type=0; else if(strcmp(str,"Diamond")==0) cnt=4,type=1; else if(strcmp(str,"Rectangle")==0) cnt=5,type=2; else cnt=4,type=3; for(int i=0;i<cnt;i++) scanf("%d",&data[i]); } }op[M]; struct List { bool vis[M]; int rht[M]; void clear() { for(int i=0;i<m;i++) vis[i]=0,rht[i]=i+1; } int jump(int pos) { if(!vis[pos]) return pos; else return rht[pos]=jump(rht[pos]); } int erase(int st, int ed) { st=max(0,st); ed=min(m-1,ed); int sum=0,pos=jump(st); while (pos<=ed) { ++sum; vis[pos]=1; pos=jump(pos); } return sum; } }row[N]; int main() { while(scanf("%d%d%d",&n,&m,&q)!=EOF) { int cnt[12]={0}; for(int i=0;i<n;i++) row[i].clear(); for(int i=0;i<q;i++) op[i].input(); for(int i=q-1;i>=0;i--) { if(op[i].type==0) { int xc=op[i].data[0]; int yc=op[i].data[1]; int r=op[i].data[2]; int c=op[i].data[3]; for(int x=max(0,xc-r);x<=min(n-1,xc+r);x++) { int dis=floor(sqrt(1.0*r*r-1.0*(x-xc)*(x-xc))); cnt[c]+=row[x].erase(yc-dis,yc+dis); } } else if(op[i].type==1) { int xc=op[i].data[0]; int yc=op[i].data[1]; int r=op[i].data[2]; int c=op[i].data[3]; for(int x=max(0,xc-r);x<=min(n-1,xc+r);x++) { int dis=r-(x-xc>0?x-xc:-(x-xc)); cnt[c]+=row[x].erase(yc-dis,yc+dis); } } else if(op[i].type==2) { int xc=op[i].data[0]; int yc=op[i].data[1]; int l=op[i].data[2]; int w=op[i].data[3]; int c=op[i].data[4]; for(int x=max(0,xc);x<min(n,xc+l);x++) { cnt[c]+=row[x].erase(yc,yc+w-1); } } else { int xc=op[i].data[0]; int yc=op[i].data[1]; int w=op[i].data[2]; int c=op[i].data[3]; for(int x=max(0,xc);x<min(n,xc+(w+1)/2);x++) { int dis=(w-1)/2-(x-xc); cnt[c]+=row[x].erase(yc-dis,yc+dis); } } } for(int i=1;i<=9;i++) printf("%d%c",cnt[i],i==9?'\n':' '); } return 0; }