Fotolog
Volver a la lista de problemas
SCUD Busters
109.c
/* SCUD Busters */
#include <stdio.h>
#include <stdlib.h>
#define DEBUG 0
typedef struct {
int x;
int y;
} punto;
struct kingdom {
int light;
int num_sites;
int num_vertices;
punto sites[101];
};
struct kingdom k[20];
int
minang(int o, int N, punto * p) {
int i,m=!o;
for (i=o+1 ; i<N ; i++) {
int ix,iy,mx,my;
ix = p[i].x-p[o].x;
iy = p[i].y-p[o].y;
mx = p[m].x-p[o].x;
my = p[m].y-p[o].y;
if (ix*my > iy*mx) {
m=i;
} else if (ix*my == iy*mx) {
if ((ix*ix + iy*iy) > (mx*mx + my*my)) {
m=i;
}
}
}
return m;
}
int
convex_hull(int N, punto * p) {
int i,m=0;
punto q;
for (i=1;i<N;i++) {
int c = p[i].y - p[m].y;
if (c<0) m=i;
if (!c && (p[i].x < p[m].x)) m=i;
}
q=p[0]; p[0]=p[m]; p[m]=q;
i=0; m=1;
while (1) {
i = minang(m-1,N,p);
if (i==0) return m;
q=p[m]; p[m]=p[i]; p[i]=q;
m++;
}
}
int pilalen;
int pila[100];
void
calc_vertices(int num)
{
k[num].num_vertices = convex_hull(k[num].num_sites, k[num].sites);
k[num].sites[k[num].num_vertices] = k[num].sites[0];
}
int
inside(int a, int b, int num)
{
int result=1;
int i;
for(i=0; i<k[num].num_vertices; i++) {
int v0x, v0y, v1x, v1y;
v0x = (k[num].sites[i+1].x - k[num].sites[i].x);
v0y = (k[num].sites[i+1].y - k[num].sites[i].y);
v1x = (a - k[num].sites[i].x);
v1y = (b - k[num].sites[i].y);
if (v0x*v1y <= v0y*v1x) {
result=0;
break;
}
}
#if DEBUG
printf("inside(%d,%d,%d)=%d\n", a, b, num, result);
#endif
return result;
}
double
area(int num)
{
int i;
int a=0;
for(i=1; i<=k[num].num_vertices; i++) {
a += k[num].sites[i-1].x*k[num].sites[i].y;
a -= k[num].sites[i].x*k[num].sites[i-1].y;
}
return ((double)a)/2;
}
#if DEBUG
void
display_kingdom(int num) /* debug */
{
int i;
printf("\nKingdom #%d\n", num);
printf("num_vertices: %d\n", k[num].num_vertices);
for(i=0; i<k[num].num_sites; i++) {
printf("SITE: %d %d\n", k[num].sites[i].x, k[num].sites[i].y);
}
printf("Area: %.2f\n", area(num));
}
#endif
int
main(void)
{
int i,N;
double tot_area=0.0;
int num_k=0;
while(1) {
scanf("%d", &N);
if (N==-1) {
break;
}
if (N<3 || N>100) {
abort();
}
k[num_k].light=1;
k[num_k].num_sites=N;
k[num_k].num_vertices=0;
for(i=0; i<N; i++) {
scanf("%d %d", &k[num_k].sites[i].x, &k[num_k].sites[i].y);
}
num_k++;
}
for(i=0; i<num_k; i++) {
calc_vertices(i);
#if DEBUG
display_kingdom(i);
#endif
}
while(1) {
int a,b;
if (scanf("%d %d", &a, &b) != 2) {
break;
}
for(i=0; i<num_k; i++) {
if (k[i].light && inside(a, b, i)) {
tot_area += area(i);
k[i].light = 0;
/* break; */
}
}
}
printf("%.02f\n", tot_area);
#if DEBUG
printf("\nResumen\n-------\n");
for(i=0; i<num_k; i++) {
printf("Kingdom %02d, light=%s, area=%5.2f\n", i, k[i].light ? "YES" : "NO ", area(i));
}
#endif
exit(0);
}









