Created
September 11, 2012 16:27
-
-
Save ynh/3699666 to your computer and use it in GitHub Desktop.
Circle Fail
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//============================================================================ | |
// 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