hdu 6127

http://acm.hdu.edu.cn/showproblem.php?pid=6127

题意:有N个点,每一个点都有一个权值,每两点可以组成一条边,每一个边的权值为两点的权值相乘,然后求一条直线可以穿过权值和最多的边为多少

思路:枚举,枚举每一个点与原点连成的直线,把所有的点分成两半,它的权值和就是两边的总和相乘。

根据极角进行排序,排序完后可以把这些点分为两部分,a部分的x是大于0的值的和,b部分的x是小于0的值的和,依次遍历这个序列,如果当前序列的点是大于0的,那么这个点可以

从a移到b,同时a,b进行更新,然后在与之前的值比较大小,最后取最大的即可

 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <iostream>
 4 #include <math.h>
 5 #include <algorithm>
 6 #define eps 1e-7
 7 using namespace std;
 8
 9 struct Node{
10     int x,y,val;
11     double the;
12 }node[500005];
13
14 bool cmp(const Node &a,const Node &b)
15 {
16     if(a.the-b.the>1e-7)
17         return true;
18     else
19         return false;
20 }
21
22 int main()
23 {
24     int t,n;
25     scanf("%d",&t);
26     while(t--)
27     {
28         scanf("%d",&n);
29         for(int i = 1;i<=n;i++)
30         {
31             scanf("%d%d%d",&node[i].x,&node[i].y,&node[i].val);
32             node[i].the = atan(1.0*node[i].y/node[i].x);
33         }
34         int suml,sumr;
35         long long ans;
36         suml = sumr = ans = 0;
37            sort(node+1,node+1+n,cmp);
38         for(int i = 1;i<=n;i++)
39             if(node[i].x>0)
40                 suml+=node[i].val;
41             else
42                 sumr+=node[i].val;
43         ans = suml*sumr;
44         for(int i = 1;i<=n;i++)
45         {
46             if(node[i].x>0)
47                 suml-=node[i].val,sumr+=node[i].val;
48             else
49                 suml+=node[i].val,sumr-=node[i].val;
50             ans = max(ans,(long long)suml*sumr);
51         }
52         printf("%lld\n",ans);
53     }
54     return 0;
55 }
时间: 2024-12-30 05:49:47

hdu 6127的相关文章

【极角排序+双指针线性扫】2017多校训练七 HDU 6127 Hard challenge

acm.hdu.edu.cn/showproblem.php?pid=6127 [题意] 给定平面直角坐标系中的n个点,这n个点每个点都有一个点权 这n个点两两可以连乘一条线段,定义每条线段的权值为线段两端点点权的乘积 现在要过原点作一条直线,要求这条直线不经过任意一个给定的点 在所有n个点两两连成的线段中,计算与这条直线有交点的线段的权值和 最大化这个权值和并输出 题目保证,给定的n个点不重合且任意两个点的连线不经过原点 [思路] 一条经过原点的直线把n个点分成两个半平面A,B 假设A中的点权

hdu 6127 : Hard challenge (2017 多校第七场 1008)(计算几何)

题目链接 题意:二维平面上有n个点(没有重叠,都不在原点,任意两点连线不过原点),每个点有一个权值,用一条过原点的直线把他们划分成两部分,使两部分的权值和的乘积最大.输出最大的乘积. 极角排序后,将原来(-pi,pi]区间的元素copy到(pi,3pi],用双指针维护一个角度差不超过pi的区间,记区间的权值和为sum1,用sum1*(sum-sum)更新ans #include<bits/stdc++.h> using namespace std; typedef long long LL;

HDU 6127: Hard challenge

Hard challenge #include<bits/stdc++.h>typedef long long L;using namespace std;#define endl '\n'const int MAXN=5*1e4+5;struct Point{ int x,y,val;}p[MAXN];bool cmp(const Point &x,const Point &y){ if(x.x==0)return true; if(y.x==0)return false;

HDU 6127 Hard challenge (极角扫描)

题意:给定 n 个点,和权值,他们两两相连,每条边的权值就是他们两个点权值的乘积,任意两点之间的直线不经过原点,让你从原点划一条直线,使得经过的直线的权值和最大. 析:直接进行极角扫描,从水平,然后旋转180度,就可以计算出一个最大值,因为题目说了任意直线不是经过原点的,所以就简单了很多,每次碰到的肯定是一个点,而不是多个点. 代码如下: #pragma comment(linker, "/STACK:1024000000,1024000000") #include <cstdi

HDU多校2017第7场

6121 Build a tree 6125 Free from square 6126 Give out candies 6127 Hard challenge 6128 Inverse of sum 6129 Just do it 对于变换$m$次之后的序列,考虑$a_0$对$a_i(0 \le i < n)$的贡献,为$C_{m-1+i}^i$个$a_0$相异或的结果.同样地,$a_1$对$a_{i+1}(0 \le i<n-1)$的贡献也为$C_{m-1+i}^i$.然后,组合数判定奇

HDU 6203 ping ping ping [LCA,贪心,DFS序,BIT(树状数组)]

题目链接:[http://acm.hdu.edu.cn/showproblem.php?pid=6203] 题意 :给出一棵树,如果(a,b)路径上有坏点,那么(a,b)之间不联通,给出一些不联通的点对,然后判断最少有多少个坏点. 题解 :求每个点对的LCA,然后根据LCA的深度排序.从LCA最深的点对开始,如果a或者b点已经有点被标记了,那么continue,否者标记(a,b)LCA的子树每个顶点加1. #include<Bits/stdc++.h> using namespace std;

HDU 5542 The Battle of Chibi dp+树状数组

题目:http://acm.hdu.edu.cn/showproblem.php?pid=5542 题意:给你n个数,求其中上升子序列长度为m的个数 可以考虑用dp[i][j]表示以a[i]结尾的长度为j的上升子序列有多少 裸的dp是o(n2m) 所以需要优化 我们可以发现dp的第3维是找比它小的数,那么就可以用树状数组来找 这样就可以降低复杂度 #include<iostream> #include<cstdio> #include<cstring> #include

hdu 1207 汉诺塔II (DP+递推)

汉诺塔II Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 4529    Accepted Submission(s): 2231 Problem Description 经典的汉诺塔问题经常作为一个递归的经典例题存在.可能有人并不知道汉诺塔问题的典故.汉诺塔来源于印度传说的一个故事,上帝创造世界时作了三根金刚石柱子,在一根柱子上从下往

[hdu 2102]bfs+注意INF

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2102 感觉这个题非常水,结果一直WA,最后发现居然是0x3f3f3f3f不够大导致的--把INF改成INF+INF就过了. #include<bits/stdc++.h> using namespace std; bool vis[2][15][15]; char s[2][15][15]; const int INF=0x3f3f3f3f; const int fx[]={0,0,1,-1};