2013-12-01 18:35:19Morris
[UVA][外接圓] 10439 - Temple of Dune
Problem A: Temple of Dune
The Archaeologists of the Current Millenium (ACM) now and then discover ancient artifacts located at the vertices of regular polygons. In general it is necessary to move one sand dune to uncover each artifact. After discovering three artifacts, the archaeologists wish to compute the minimum number of dunes that must be moved to uncover all of them.The first line of input contains a positive integer n, the number of test cases. Each test case consists of three pairs of real numbers giving the x and y coordinates of three vertices from a regular polygon. For each line of input, output a single integer stating the fewest vertices that such a polygon might have.
You may assume that each input case gives three distinct vertices of a regular polygon with at most 200 vertices.
Sample input
4 10.00000 0.00000 0.00000 -10.00000 -10.00000 0.00000 22.23086 0.42320 -4.87328 11.92822 1.76914 27.57680 156.71567 -13.63236 139.03195 -22.04236 137.96925 -11.70517 129.400249 -44.695226 122.278798 -53.696996 44.828427 -83.507917
Output for the sample input
4 6 23 100
題目描述:
給三點座標,求最小 n 多邊形包含這三點。
保證 n 不大於 200。
題目解法:
求出三點的外接圓,依序窮舉最小的 n 多邊形,#include <stdio.h>
從外接圓圓心拉向量,依序旋轉 theta = 2pi/n 度,檢查是否三點都在上面。
這題的誤差容忍還真有點大。
#include <math.h>
struct Pt {
double x, y;
};
Pt circle(Pt p1, Pt p2, Pt p3) {
double a, b, c, d, e, f;
double dx, dy, dd;
a = p1.x - p2.x, b = p1.y - p2.y;
c = a*((p1.x+p2.x)/2) + b*((p1.y+p2.y)/2);
d = p2.x - p3.x, e = p2.y - p3.y;
f = d*((p2.x+p3.x)/2) + e*((p2.y+p3.y)/2);
Pt o;
dd = a*e - b*d;
dx = c*e - b*f;
dy = a*f - d*c;
o.x = dx/dd, o.y = dy/dd;
return o;
}
int main() {
int testcase;
int i, j, n;
const double pi = acos(-1);
scanf("%d", &testcase);
while(testcase--) {
Pt a, b, c;
scanf("%lf %lf", &a.x, &a.y);
scanf("%lf %lf", &b.x, &b.y);
scanf("%lf %lf", &c.x, &c.y);
Pt o = circle(a, b, c);
for(n = 3; n <= 200; n++) {
Pt prev = a, next;
double theta = 2*pi/n;
double sintheta = sin(theta);
double costheta = cos(theta);
double vx, vy, tx, ty;
int same = 1;
for(i = 0; i < n; i++) {
vx = prev.x - o.x, vy = prev.y - o.y;
next.x = o.x + vx*costheta - vy*sintheta;
next.y = o.y + vx*sintheta + vy*costheta;
prev = next;
/*if(n == 23)
printf("%lf %lf\n", prev.x, prev.y);*/
#define eps 1e-4
if(fabs(prev.x - b.x) < eps && fabs(prev.y - b.y) < eps)
same++;
if(fabs(prev.x - c.x) < eps && fabs(prev.y - c.y) < eps)
same++;
}
if(same == 3)
break;
}
printf("%d\n", n);
}
return 0;
}