Skip to content

Instantly share code, notes, and snippets.

@ynh
Created September 11, 2012 16:27
Show Gist options
  • Save ynh/3699666 to your computer and use it in GitHub Desktop.
Save ynh/3699666 to your computer and use it in GitHub Desktop.
Circle Fail
//============================================================================
// Name : CirclesC.cpp
// Author :
// Version :
// Copyright : Your copyright notice
// Description : Hello World in C++, Ansi-style
//============================================================================
#include <iostream>
#include <cstdio>
#include <cmath>
#include <vector>
#include <algorithm>
using namespace std;
int w, h, n, x, y, r, count, l;
struct Interval {
public:
int y;
bool start;
Interval(int ay, int astart) {
y = ay;
start = astart;
}
};
struct Circle {
public:
int x;
int s;
int y;
int r;
int r2;
int en;
int* xs;
Circle() {
}
Circle(int ax, int ay, int ar) {
x = ax;
y = ay;
r = ar;
r2 = r * r;
s = max(0, x - r);
en = min(w - 1, x + r);
xs = new int[r + 1];
for (int i = 0; i <= r; ++i) {
xs[i] = sqrt(r2 - (i) * (i));
}
}
int getStart() {
return s;
}
int getEnd() {
return en;
}
int getStartY() {
return y - r;
}
int getEndY() {
return y + r;
}
int height(int x1) {
return xs[abs(x1 - x)];
}
};
int inters(int s1, int e1, int s2, int e2) {
return max(min(min(e1 + 1, e2 + 1), h) - max(max(s1, s2), 0), 0);
}
int interpolate(Circle* c) {
int total = 0;
for (int x = c->getStart(); x <= c->getEnd(); ++x) {
int h1 = c->height(x);
total += min(c->y + h1 + 1, h) - max(c->y - h1, 0);
}
return total;
}
int diffinterpolate(Circle* c, Circle* b) {
if (max(c->getStartY(), b->getStartY())
<= min(c->getEndY(), b->getEndY())) {
int total = 0, h1, h2, en = min(c->getEnd(), b->getEnd());
for (int x = max(c->getStart(), b->getStart()); x <= en; ++x) {
h1 = c->height(x);
h2 = b->height(x);
total += inters(c->y - h1, c->y + h1, b->y - h2, b->y + h2);
}
return total;
} else {
return 0;
}
}
bool interval_sorter(Circle const& lhs, Circle const& rhs) {
return lhs.y + lhs.r > rhs.y + lhs.r;
}
int main() {
Circle* circles;
scanf("%d", &l);
for (int q = 0; q < l; ++q) {
int co = 0;
scanf("%d %d %d", &w, &h, &n);
circles = new Circle[n];
for (int i = 0; i < n; ++i) {
scanf("%d %d %d", &x, &y, &r);
circles[i] = Circle(x, y, r);
co += interpolate(&(circles[i]));
}
int elements = sizeof(circles) / sizeof(circles[0]);
std::sort(circles, circles + elements, &interval_sorter);
for (int i = 0; i < n; ++i) {
for (int j = 0;
j < i && circles[i].getStartY() < circles[j].getEndY();
++j) {
co -= diffinterpolate(&(circles[i]), &(circles[j]));
}
}
printf("%d\n", (w * h - co));
delete circles;
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment