zoukankan      html  css  js  c++  java
  • hdu 6127 Hard challenge(极角/角度排序+枚举+结构体排序新写法)

    Hard challenge

    Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 524288/524288 K (Java/Others)
    Total Submission(s): 1083    Accepted Submission(s): 444

    Problem Description
    There are n points on the plane, and the ith points has a value vali, and its coordinate is (xi,yi). It is guaranteed that no two points have the same coordinate, and no two points makes the line which passes them also passes the origin point. For every two points, there is a segment connecting them, and the segment has a value which equals the product of the values of the two points. Now HazelFan want to draw a line throgh the origin point but not through any given points, and he define the score is the sum of the values of all segments that the line crosses. Please tell him the maximum score.
     
    Input
    The first line contains a positive integer T(1T5), denoting the number of test cases.
    For each test case:
    The first line contains a positive integer n(1n5×104).
    The next n lines, the ith line contains three integers xi,yi,vali(|xi|,|yi|109,1vali104).
     
    Output
    For each test case:
    A single line contains a nonnegative integer, denoting the answer.
     
    Sample Input
    2
    2
    1 1 1
    1 -1 1
    3
    1 1 1
    1 -1 10
    -1 0 100
     
     
    Sample Output
    1
    1100
    Source
     
    Recommend
    liuyiding   |   We have carefully selected several similar problems for you:  6132 6131 6130 6129 6128 
     
     
     
    题目大意
    给出n个点的坐标和权值val,任意两点之间都有线段连接,线段的权值是两端点权值的乘积(题目保证,没有两个点坐标相同,并且没有两个点的连线过原点)。现在要求过原点做一条直线,使直线穿过的所有线段的权值和最大。
    题解:极角排序后扫描线
     
    #include <iostream>
    #include
    <cstdio> #include<algorithm> #include<cmath> using namespace std; #define ll long long const int maxn=50005; const double pi=acos(-1.0); ll ans,sum,half; int T,n; struct node { ll x,y,val; double angle; // bool operator <(const node &p)const//重载运算符 < // { // return angle<p.angle; // } //后面sort(a+1;a+1+n); }a[maxn]; bool cmp(node a,node b) { return a.angle<b.angle; } int main() { scanf("%d",&T); while(T--) { scanf("%d",&n); sum=0; half=0; for(int i=1;i<=n;i++) { scanf("%lld%lld%lld",&a[i].x,&a[i].y,&a[i].val); if(a[i].x==0) a[i].angle=pi/2.0; else a[i].angle=atan(a[i].y*1.0/a[i].x); sum+=a[i].val; } sort(a+1,a+1+n,cmp); //角度排序,并非所说的极角排序 for(int i=1;i<=n;i++) if (a[i].x>=0) half+=a[i].val; ans=half*(sum-half); for(int i=1;i<=n;i++) { if (a[i].x>=0) half-=a[i].val; else half+=a[i].val; ans=max(ans,half*(sum-half)); } printf("%lld ",ans); } return 0; }

      

    stl函数 atan & atan2

    在C语言的math.h或C++中的cmath中有两个求反正切的函数atan(double x)与atan2(double y,double x)  他们返回的值是弧度 要转化为角度再自己处理下。

    前者接受的是一个正切值(直线的斜率)得到夹角,但是由于正切的规律性本可以有两个角度的但它却只返回一个,因为atan的值域是从-90~90 也就是它只处理一四象限,所以一般不用它。

    第二个atan2(double y,double x) 其中y代表已知点的Y坐标 同理x ,返回值是此点与远点连线与x轴正方向的夹角,这样它就可以处理四个象限的任意情况了,它的值域相应的也就是-180~180了

    如:

    例1:斜率是1的直线的夹角

    cout<<atan(1.0)*180/PI;//45°

    cout<<atan2(1.0,1.0)*180/PI;//45° 第一象限

    cout<<atan2(-1.0,-1.0)*180/PI;//-135°第三象限

    后两个斜率都是1 但是atan只能求出一个45°

    极角排序:

    利用arctan计算极角大小。(范围『-180,180』)

    1 bool cmp(const Point& p1, const Point& p2)
    2 {
    3     return atan2(p1.y, p1.x) < atan2(p2.y, p2.x);
    4 }
  • 相关阅读:
    asp.net超强日历
    闲话多线程的创建
    一些应该熟记于心的jQuery函数和技巧
    jQuery选择符总结
    使用OQL+SQLMAP解决ORM多表复杂的查询问题
    同样的SQL语句在查询分析器执行很快,但是网站上执行超时的诡异问题
    "开门待客"还是“送货上门”?
    使用ASP.NET MVC2+PDF.NET 构建一个简单的新闻管理程序
    使用PDF.NET数据开发框架的实体操作语言OQL构造复杂查询条件
    “批量少次”还是“少量多次”邮件通信系统效率浅谈
  • 原文地址:https://www.cnblogs.com/stepping/p/7374376.html
Copyright © 2011-2022 走看看