Photolog

Through the Looking-Glass
2010-10-12: Through the Looking-Glass
My radio speaks is binary!
2010-10-10: My radio speaks is binary!
Gigaminx: (present for my birthday)
2010-09-16: Gigaminx: (present for my birthday)
Trini on bike
2010-09-05: Trini on bike
Valporquero
2010-08-28: Valporquero
My new bike!
2010-08-22: My new bike!
Mario and Ana's wedding
2010-08-13: Mario and Ana's wedding
Canyoning in Guara
2010-08-07: Canyoning in Guara
Trini and Mari in Marbella
2010-08-05: Trini and Mari in Marbella
Trini and Chelo in Tabarca
2010-08-03: Trini and Chelo in Tabarca
Valid XHTML 1.1
Log in
Back to list of problems

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);
}