ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

3736. 【NOI2014模拟7.11】数学题(math)

2022-01-13 22:00:33  阅读:130  来源: 互联网

标签:node return 7.11 qy px NOI2014 ge vec 3736


Description

给定两个向量 \(\mathbf{a}=\left(x_{1}, y_{1}\right), \mathbf{b}=\left(x_{2}, y_{2}\right)\) 。求出一对整数 \(\lambda_{1}, \lambda_{2}\), 使得 \(\left|\lambda_{1} \mathbf{a}+\lambda_{2} \mathbf{b}\right|\) 最小 \((|\mathrm{v}|\) 表示向量 \(\mathrm{v}\) 的长度 \()\) 。要求 \(\lambda_{1}, \lambda_{2}\) 不同时为 0 。

Solution

引理 1:当两向量夹角 \(\theta>\frac{\pi}{3}\),即 \(\cos \theta<\frac{1}{2}\) 时,答案为\(\min(|\vec{a}|,|\vec{b}|)^2\)。

证明:

令 \(p=|a|,q=|b|\),不妨设 \(p<q\),则

\(\begin{aligned}|\vec{a}x+\vec{b}y|&=\sqrt{(px)^2+(qy)^2-2pxqy\cos \theta}\\&\ge\sqrt{|px|^2+|qy|^2-2|px||qy|\cos \theta}\\&\ge\sqrt{|px|^2+|qy|^2-|px||qy|}\\&\ge\sqrt{(|px|-|qy|)^2+|px||qy|}\end{aligned}\)

若 \(x=0\),则 \(y\not=0\),\((|px|-|qy|)^2=|qy|^2\ge q^2\ge p^2\)

若 \(y=0\),则 \(x\not=0\),\((|px|-|qy|)^2=|px|^2\ge p^2\)

否则 \(|px||qy|\ge |p||q|\ge p^2\)

引理 2:\((a,b)\) 所对应的答案,和 \((a,b+ka)\) 一致,其中 \(k\) 为整数。

证明:

令 \(|ax+by|\) 为所求答案,则 \(|a(x-ky)+(b+ka)y|\) 也是,即 \((x,y)\) 对应着答案 \((x-ky,y)\)。并且若 \((x,y)\not=(0,0)\),则 \((x-ka,y)\not=(0,0)\)。同理可证相反方向。

根据这两个引理,那么使用欧几里得算法就是显而易见的。

通过引理 2 的变换,将两向量的夹角满足引理 1 的条件,就是我们的目标。

但我们还要求出在引理 2 中提到的 \(k\)。这里我们规定 \(|\vec{a}|\le|\vec{b}|\)。

令 \(c=ka\)。

如果 \(k<1\),那么可以证得 \(\vec{b}=\vec{b}-\vec{a}\) 是符合要求的变换。

如果 \(k>1\),那么将 \(k\) 下取整,即可保证 \(ka\le c\),那么 \(\vec{b}=\vec{b}-\vec{a}k\)即可。

Code

#include<cmath>
#include<cstdio>
#include<algorithm>
#define ll long long
#define db double
using namespace std;
struct node
{
    ll x,y;
    db len() {return sqrt((db)x*x+y*y);}
    int operator*(node b) {return x*b.x+y*b.y;}
    node operator*(ll b) {return (node){x*b,y*b};}
    node operator+(node b) {return (node){x+b.x,y+b.y};}
    node operator-(node b) {return (node){x-b.x,y-b.y};}
}x,y,z;
db calc_cos(node a,node b) {return (db)(a*b)/(a.len()*b.len());}
int main()
{
    freopen("math.in","r",stdin);
    freopen("math.out","w",stdout);
    while (scanf("%lld%lld%lld%lld",&x.x,&x.y,&y.x,&y.y)!=EOF)
    {
        if (x.x*y.y==x.y*y.x)
        {
            printf("%d\n",0);
            continue;
        }
        if (x*x>y*y) swap(x,y);
        if (x*y<0) y=y*-1;
        db co=calc_cos(x,y);
        while (co>0.5)
        {
            if (x*x>y*y) swap(x,y);
            if (x*y<0) y=y*-1;
            if (x*y/(x*x)<=1) y=y-x;
            else
            {
                z=x*(x*y/(x*x));
                y=y-z;
            }
            co=calc_cos(x,y);
        }
        printf("%lld\n",min(x*x,y*y));
    }
    return 0;
}

标签:node,return,7.11,qy,px,NOI2014,ge,vec,3736
来源: https://www.cnblogs.com/Livingston/p/15799838.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有