UVALive 5873 (几何+思维)

唉 被秀了。。。 还是太弱,说好的数形结合呢,列个式子出来后就被吓到了,然后就懵逼了。

题意:

有一条狗,从原点出发,沿n个向量走,每个向量只走一次,沿着一个向量(x,y)走时,既可以往(x,y)方向走,也可以往(-x,-y)方向走。 然后问这条狗离原点最远的距离。

如果写成方程:

n个向量分别表示为: (x1,y1) (x2,y2) (x3,y3) ... (xn,yn)

第i个向量往(xi,yi)方向则ai=1,否则ai=-1

则ans = (a1*x1+a2*x2+...+an*xn)^2 + (a1*y1+a2*y2+...+an*yn)^2

要你给出一个(a1,a2,...,an)使得ans最大。

我以为写出方程形式会有助于做题,然并卵。。。

这题还是要用直观的方法理解。。。

数形结合方法:

定理1:如果把一个向量的正方向和反方向都算上,那么最优解的n个向量必然在一个半平面内。

证明: 假设最优解中的n个向量不在一个半平面内,一定可以找到一个直线l,使得直线左右两边都存在向量,那么将直线l左边的向量都转变为其反向量,那么结果一定大于最优解。

定理2: 如果把一个向量的正方向和反方向都算上,并以对x正半轴夹角排序,则连续的n个向量必两两不同(即不会存在一个向量的正向量和反向量都存在的情况)。

证: 显然。

由这两个定理,那么这题就很好做了,把所有的(xi,yi)(-xi,-yi)都算上,然后进行极角排序,枚举连续的n个记录最大值即可。

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <algorithm>
using namespace std;
#define N 110
const double PI         = acos(-1.0);// PI

struct node
{
    int x,y;
    double ang;
}g[2*N];

double GetAngle(double x,double y)
{
    double tmp=atan2(y,x);
    if(tmp<0) tmp=2*PI+tmp;
    return tmp;
}

double dis(int x,int y)
{
    return sqrt((double)x*x+(double)y*y);
}

int cmp(node t1,node t2)
{
    return t1.ang<t2.ang;
}

//泥煤,完全想错了。。。

int main(int argc, const char * argv[]) {
    int n;
    while(scanf("%d",&n) && n)
    {
        int cnt=0;
        for(int i=0;i<n;i++)
        {
            int x,y;
            scanf("%d%d",&x,&y);
            g[cnt].x=x; g[cnt].y=y; g[cnt].ang=GetAngle(x, y);
            cnt++;
            g[cnt].x=-x; g[cnt].y=-y; g[cnt].ang=GetAngle(-x, -y);
            cnt++;
        }
        sort(g,g+cnt,cmp);
        int pi,pj;
        pi=0;
        double ans=0;
        for(;pi<cnt;pi++)
        {
            int x=0,y=0;
            pj=pi;
            for(int j=0;j<n;j++)
            {
                x+=g[pj].x;
                y+=g[pj].y;
                pj=(pj+1)%cnt;
            }
            ans=max(ans,dis(x,y));
        }
        /*
        ans*=10000;
        int tmp=((long long)ans)%10;
        ans/=10;
        if(tmp>5) ans++;
        ans/=1000;
        char strans[110];
        sprintf(strans,"%lf",ans);
        for(int i=0;i<100;i++)
        {
            if(strans[i] == ‘.‘)
            {
                printf("%c",strans[i]);
                for(int j=0;j<3;j++)
                {
                    printf("%c",strans[i+1+j]);
                }
                break;
            }
            else printf("%c",strans[i]);
        }
        printf("\n");
         */
        printf("%.3lf\n",ans);
    }
    return 0;
}

PS:最后题目中说的四舍五入是扯淡,直接%.3lf即可。

时间: 2024-10-03 14:14:54

UVALive 5873 (几何+思维)的相关文章

[CodeForces]CodeForces - 13D 几何 思维

大致题意: 给出N个红点和M个蓝点,问可以有多少个红点构成的三角形,其内部不含有蓝点 假设我们现在枚举了一条线段(p[i],p[j]),我们可以记录线段下方满足(min(p[i].x,p[j].x)<x<=max(p[i].x,p[j].x) 的数量  时间复杂度为O(N*N*M) 那么我们就可以枚举三角形O(1)判断三角形内有无红点. 1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4

【转】 CATransform3D 矩阵变换之立方体旋转实现细节

原文网址:http://blog.csdn.net/ch_soft/article/details/7351896 第一部分.前几天做动画,使用到了CATransform3D ,由于没有学过计算机图形学,矩阵中m11--m44的各个含义都不清楚,经过几天研究总结如下:(供和我一样的菜鸟学习) struct CATransform3D { CGFloat m11(x缩放), m12(y切变), m13(), m14(); CGFloat m21(x切变), m22(y缩放), m23(), m24

一些对数学领域及数学研究的个人看法(转载自博士论坛wcboy)

转自:http://www.math.org.cn/forum.php?mod=viewthread&tid=14819&extra=&page=1 原作者: wcboy 现在的论坛质量比以前差了,大部分都是来解题问答的,而且层次较低.以前论坛中,Qullien很令人印象深刻,但愿他能在国外闯出一片天空.现在 基础数学版代数&数论子版中那几个讨论代数几何的还不错.不期望目前论坛出现很多高层次高手,高层次高手应该站在好课题上高观点讨论数学,出 现这样的网友,看他们的言论非常过

中考数学知识点汇总

第一章        有理数 一.知识框架 二.知识概念 1.有理数: (1)凡能写成 形式的数,都是有理数.正整数.0.负整数统称整数:正分数.负分数统称分数:整数和分数统称有理数.注意:0即不是正数,也不是负数:-a不一定是负数,+a也不一定是正数:p不是有理数: (2)有理数的分类:    ①   ② 2.数轴:数轴是规定了原点.正方向.单位长度的一条直线. 3.相反数: (1)只有符号不同的两个数,我们说其中一个是另一个的相反数:0的相反数还是0: (2)相反数的和为0 ? a+b=0 

UVALive 6092 Catching Shade in Flatland --枚举+几何计算

题意:x=[-200,200],y=[-200,200]的平面,一天中太阳从不同角度射到长椅(原点(0,0))上,有一些树(用圆表示),问哪个时刻(分钟为单位)太阳光线与这些圆所交的弦长总和最长.太阳距离原点总是500m.(这些圆不会互相相交,每个圆都不包括原点或者不经过原点) 解法:直接暴力24*60分钟,找出此时的角度,然后求出直线方程,再枚举每个圆,求出弦长.注意这里每个圆都不包括原点,所以直线与圆的交点一定在同一侧,所以..我当时想多了,没看清题目.把他当成可以包含原点了,代码超长,幸好

UVALive - 3263 That Nice Euler Circuit (几何)

UVALive - 3263 That Nice Euler Circuit (几何) ACM 题目地址: UVALive - 3263 That Nice Euler Circuit 题意: 给出一个点,问连起来后的图形把平面分为几个区域. 分析: 欧拉定理有:设平面图的顶点数.边数.面数分别V,E,F则V+F-E=2 大白的题目,做起来还是很有技巧的. 代码: /* * Author: illuz <iilluzen[at]gmail.com> * File: LA3263.cpp * C

UVALive 6602 Counting Lattice Squares 【几何】【机智】

题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=4613 题目大意:给你一个n*m的矩阵格子,在这n*m的矩阵格子中要你选出四个点,形成一个正方形,让正方形的面积为奇数,问可以形成多少个这样的正方形. 题目思路:从每一个奇数开始作为一个基本单元. 面积     边 能组成的正方形: 1*1      1      

思维 UVALive 3708 Graveyard

题目传送门 1 /* 2 题意:本来有n个雕塑,等间距的分布在圆周上,现在多了m个雕塑,问一共要移动多少距离: 3 思维题:认为一个雕塑不动,视为坐标0,其他点向最近的点移动,四舍五入判断,比例最后乘会10000即为距离: 4 详细解释:http://www.cnblogs.com/zywscq/p/4268556.html 5 */ 6 #include <cstdio> 7 #include <iostream> 8 #include <algorithm> 9 #

简单几何(判断矩形的位置) UVALive 7070 The E-pang Palace (14广州B)

题目传送门 题意:给了一些点,问组成两个不相交的矩形的面积和最大 分析:暴力枚举,先找出可以组成矩形的两点并保存起来(vis数组很好),然后写个函数判断四个点是否在另一个矩形内部.当时没有保存矩形,用for来找矩形,结果写糊涂了忘记判断回形的情况... /************************************************ * Author :Running_Time * Created Time :2015/11/6 星期五 17:00:44 * File Name