题意:一个画板上可以画4种图形,画板被分成n*m个网格,给出了每种图形的坐标大小和颜色,画了q次后,问画板上每种颜色占多少格子。
题解:因为只要最后被覆盖的颜色,所以倒着操作,这样已经画过的地方就不再计算,未画过的就并到已画的集合内,方便统计数量。
#include <stdio.h>
#include <algorithm>
#include <string.h>
#include <cmath>
using namespace std;
const int N = 50005;
int n, m, q, color[10], pa[205][N];
char str[20];
struct S {
int xc, yc, r, l, w, c, flag;
}s[N];
int get_parent(int *pa, int x) {
return pa[x] == x ? x : pa[x] = get_parent(pa, pa[x]);
}
void solve(int l, int r, int *pa, int c) {
l = get_parent(pa, l);
while (l <= r) {
color[c]++;
pa[l] = get_parent(pa, l + 1);
l = pa[l];
}
}
void count_d(int xc, int yc, int r, int c) {
for (int x = max(0, xc - r); x <= min(n - 1, xc + r); x++) {
int rr = r - abs(x - xc);
int l1 = max(0, yc - rr), r1 = min(m - 1, yc + rr);
solve(l1, r1, pa[x], c);
}
}
void count_c(int xc, int yc, int r, int c) {
for (int x = max(0, xc - r); x <= min(n - 1, xc + r); x++) {
int rr = (int)(sqrt(r * r - (x - xc) * (x - xc)));
int l1 = max(0, yc - rr), r1 = min(m - 1, yc + rr);
solve(l1, r1, pa[x], c);
}
}
void count_t(int xc, int yc, int w, int c) {
for (int x = max(0, xc); x <= min(n - 1, xc + (w + 1) / 2 - 1); x++) {
int ww = ((w + 1) / 2 - 1) - (x - xc);
int l1 = max(0, yc - ww), r1 = min(m - 1, yc + ww);
solve(l1, r1, pa[x], c);
}
}
void count_r(int xc, int yc, int l, int w, int c) {
for (int x = max(0, xc); x <= min(n - 1, xc + l - 1); x++) {
int l1 = max(0, yc), r1 = min(m - 1, yc + w - 1);
solve(l1, r1, pa[x], c);
}
}
int main() {
while (scanf("%d%d%d", &n, &m, &q) == 3) {
for (int i = 0; i < n; i++)
for (int j = 0; j <= m; j++)
pa[i][j] = j;
memset(color, 0, sizeof(color));
for (int i = 0; i < q; i++) {
scanf("%s", str);
if (str[0] == 'R') {
scanf("%d%d%d%d%d", &s[i].xc, &s[i].yc, &s[i].l, &s[i].w, &s[i].c);
s[i].flag = 3;
}
else if (str[0] == 'T') {
scanf("%d%d%d%d", &s[i].xc, &s[i].yc, &s[i].r, &s[i].c);
s[i].flag = 2;
}
else if (str[0] == 'C') {
scanf("%d%d%d%d", &s[i].xc, &s[i].yc, &s[i].r, &s[i].c);
s[i].flag = 1;
}
else {
scanf("%d%d%d%d", &s[i].xc, &s[i].yc, &s[i].r, &s[i].c);
s[i].flag = 0;
}
}
for (int i = q - 1; i >= 0; i--) {
if (s[i].flag == 0)
count_d(s[i].xc, s[i].yc, s[i].r, s[i].c);
else if (s[i].flag == 1)
count_c(s[i].xc, s[i].yc, s[i].r, s[i].c);
else if (s[i].flag == 2)
count_t(s[i].xc, s[i].yc, s[i].r, s[i].c);
else if (s[i].flag == 3)
count_r(s[i].xc, s[i].yc, s[i].l, s[i].w, s[i].c);
}
printf("%d", color[1]);
for (int i = 2; i < 10; i++)
printf(" %d", color[i]);
printf("\n");
}
return 0;
}