题意:给出一个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;
}