24h購物| | PChome| 登入
2013-12-01 18:35:19| 人氣2,073| 回應0 | 上一篇 | 下一篇

[UVA][外接圓] 10439 - Temple of Dune

推薦 0 收藏 0 轉貼0 訂閱站台

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 多邊形,
從外接圓圓心拉向量,依序旋轉 theta = 2pi/n 度,檢查是否三點都在上面。

這題的誤差容忍還真有點大。
#include <stdio.h>
#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;
}

台長: Morris
人氣(2,073) | 回應(0)| 推薦 (0)| 收藏 (0)| 轉寄
全站分類: 教育學習(進修、留學、學術研究、教育概況) | 個人分類: UVA |
此分類下一篇:[UVA][Easy] 12646 - Zero or One
此分類上一篇:[UVA] 10416 - Folding My T-Shirt

是 (若未登入"個人新聞台帳號"則看不到回覆唷!)
* 請輸入識別碼:
請輸入圖片中算式的結果(可能為0) 
(有*為必填)
TOP
詳全文