Codeforces Beta Round #1 C Ancient Berland Circus

这里写图片描述

http://codeforces.com/contest/1/problem/C

题意:
有一个圆形的斗兽场, 圆上有X个树桩,
刚好能组成一个正多边形的舞台。
但是, 有3个树桩不见了。
现在给你这3个树桩的坐标, 让你判断这个舞台最小的面积。
(数组绝对合法。 绝对能组成三角形)
不会大于100边型。

分析:
给你三个点,让你找出以这三个点为顶点的面积最小的正多边形。

由于是确定是正多边形,所以一定存在外接圆.
所以可以分为如下几步:
海伦公式: p=(a+b+c)/2
S=√p(p-a)(p-b)(p-c)
1.求外接圆半径r=abc/4S
2.由余弦定理求出三个圆心角ang[3]
(要注意的是,有可能有三个点在同一段半圆弧上,
这是第三个圆心角应该用2π-ang[0]-ang[1],
所以干脆全部都是ang[2]=2π-ang[0]-ang[1])
3.求这三个角的最大公约数为A, 那么这就是一个正2π/A边形.
4.一个小三角形的面积S=1/2·r * r * sinA
5.nS即为所求.

#include <iostream>
#include <sstream>
#include <iomanip>
#include <vector>
#include <deque>
#include <list>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <bitset>
#include <string>
#include <numeric>
#include <algorithm>
#include <functional>
#include <iterator>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <complex>
#include <ctime>

const double ERR = 0.0001;

bool feq (double a, double b)
{
    return fabs(a-b) < ERR;
}

double fgcd(double a, double b)
{
    if (feq(a, 0))
        return b;
    if (feq(b, 0))
        return a;
    return fgcd(b, fmod(a, b));
}

double dist(double x0, double x1, double y0, double y1)
{
    return sqrt((x1-x0)*(x1-x0) + (y1-y0)*(y1-y0));
}


typedef long long LL;
const double pi = acos(-1.0);
const long long mod = 1e9 + 7;
using namespace std;

typedef struct
{
    double x,y;
}Point;

Point Points[5];

int main()
{
    //freopen("int.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    for(int i = 1;i <= 3;i++)
        scanf("%lf %lf",&Points[i].x,&Points[i].y);
    double l1 = dist(Points[1].x , Points[2].x , Points[1].y , Points[2].y);
    double l2 = dist(Points[1].x , Points[3].x , Points[1].y , Points[3].y);
    double l3 = dist(Points[3].x , Points[2].x , Points[3].y , Points[2].y);
    double l = (l1 + l2 + l3) / 2;
    double S = sqrt(l * (l - l1) * (l - l2) * (l - l3));
    double R = l1 * l2 * l3 / (4 * S);
    double angle1,angle2,angle3;
    angle1 = acos(1 - l1 * l1 / (2 * R * R) );
    angle2 = acos(1 - l2 * l2 / (2 * R * R) );
    angle3 = 2 * pi - angle1 - angle2;
    double theta = 0;
    theta = fgcd(theta,angle1);
    theta = fgcd(theta,angle2);
    theta = fgcd(theta,angle3);
    printf("%.6f\n", R * R * sin(theta) * pi / theta);
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值