UVA - 1643 Angle and Squares(几何+数学)

VJ原题

题意:

   给出两个点的坐标,这两个点分别与原点形成两条射线,这两条射线之间形成一个夹角。给出一些已知边长的正方形,问如何摆放,让正方形与两射线之间围成的面积最大。正方形摆放的角度随意。

思路:

   其实玄学的想一下,我们要做的就是让原点和两个交点所确定的三角形尽量大,让正方形在此三角形中的面积尽量小。一减就是答案了。最大的情况就是,三角形的底是所有正方形的对角线之和(最长),对于其确定的三角形来说,因为顶角确定了,所以根据正余弦定理可得,底边越长,高越长。我们设所有正方形边长和为tot,交点A‘(x1,k1x1),B'(x2,k2x2),由横坐标,纵坐标差都为tot可以得到方程组,解出两点坐标。

   之后一个问题就是求三角形面积。一开始的想法是硬求,求出A'B'的解析式,点到直线距离算出高,就能求出面积。后来因为涉及到很多次除法,造成了精度损失和爆存储范围。后来想到了可以吧OA'和OB'看成两个向量,根据余弦定理算出三角形的面积,也就是相当于用叉积算出面积之后,减去所有正方形的面积的一半。然后就做出来啦。这个算三角形的方法还是值得一学的。

之后就很好写啦。

#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <queue>
#include <set>
#include <map>
#include <stack>
#include <string>
#include <list>
#include <cstdlib>
#include <memory>
#include <cstring>
#include <sstream>
#include <list>
#include <deque>
#include <bitset>
#include <vector>

using namespace std;

#define INF 0x3f3f3f3f
#define PI 3.141592653579
#define FRER() freopen("input.txt" , "r" , stdin);
#define FREW()  freopen("output.txt" , "w" , stdout);
#define  QIO std::ios::sync_with_stdio(false)
#define mem(a , b) memset(a , b , sizeof(a))
const double eps = 1e-8;
typedef long long ll;
const int maxn = 100+500;

double sqa[maxn];
int main()
{
//    FRER();
//    FREW();
    int n;
    while(scanf("%d" , &n) && n)
    {
        double x1, y1, x2 , y2;
        cin >> x1 >> y1 >> x2 >> y2;
        double tot = 0;
        double k1 = y1/x1 , k2 = y2/x2;
        double di = 0 , ssum = 0;
        for(int i = 0 ; i < n ; i++)
        {
            cin >> sqa[i];
            tot += sqa[i];
            di += sqrt(2)*sqa[i];
            ssum += sqa[i]*sqa[i]/2.0;
        }
        double x3 = tot*(1.0+k1)/(k1-k2);
        double y3 = x3 * k1;
        double x4 = tot*(1.0+k2)/(k1-k2);
        double y4 = x4 * k2;
        double ress = fabs(x3*y4 - x4*y3)/2.0;
        printf("%.3lf\n" , ress-ssum );
    }
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值