hdu6127

题意

二维平面上存在一些点,每个点都有权值,任意两点组成的线段的权值为这两点权值的乘积,选定一条经过原点的直线,问怎样使得它经过的线段的权值之和最大。

分析

题目等价于用一条直线将平面上的所有点分成两部分,那么答案就是两部分点的权值和的乘积。

比如说一条与 \(y\) 轴重合的直线,它左边有点的权值 \(w_1, w_2, w_3\) ,右边 \(w_4, w_5\) ,那么这种情况下权值之和就是 \((w_1 + w_2 + w_3) * (w_4 + w_5)\) 。

计算出所有点的斜率,一三象限归为一类,二四象限归为一类,给斜率排序。

以一三象限为例,上部分一定包括第二象限的点的权值之和,下部分一定包括第四象限的点的权值之和,将斜率从小到大排序的话,那么初始状态上部分包括第一象限的点的权值之和,下部分包括第三象限的点的权值之和。枚举排序后的点,如果斜率最小的点在第一象限,把它从上部分删去,加入到下部分,计算权值之和,更新答案即可。

code

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
struct Point {
ll x, y, w;
double k;
Point() {}
Point(ll x, ll y, ll w, double k) : x(x), y(y), w(w), k(k) {}
bool operator<(const Point&p) const {
return k < p.k;
}
};
vector<Point> p1, p2;
int main() {
int T;
scanf("%d", &T);
while(T--) {
int n;
scanf("%d", &n);
ll wei[4]; // 处于坐标轴上的点
memset(wei, 0, sizeof wei);
p1.clear(); p2.clear();
ll xian1 = 0, xian2 = 0, xian3 = 0, xian4 = 0; // 每个象限点的权值之和
for(int i = 0; i < n; i++) {
ll x, y, w;
scanf("%lld%lld%lld", &x, &y, &w);
if(x == 0 && y > 0) wei[1] = w;
else if(x == 0 && y < 0) wei[3] = w;
else if(x > 0 && y == 0) wei[0] = w;
else if(x < 0 && y == 0) wei[2] = w;
else {
double k = y * 1.0 / x;
if(k > 0) {
p1.push_back(Point(x, y, w, k));
if(x > 0) xian1 += w;
else xian3 += w;
} else {
p2.push_back(Point(x, y, w, k));
if(x > 0) xian4 += w;
else xian2 += w;
}
}
}
ll ans = 0;
// 一、三象限
int up1 = xian1, down1 = 0, up3 = 0, down3 = xian3;
sort(p1.begin(), p1.end());
ans = max(ans, (wei[1] + wei[2] + xian2 + xian1) * (wei[0] + wei[3] + xian3 + xian4));
ans = max(ans, (wei[1] + wei[2] + xian2 + xian3) * (wei[0] + wei[3] + xian1 + xian4));
for(int i = 0; i < p1.size(); i++) {
if(p1[i].x > 0) { up1 -= p1[i].w; down1 += p1[i].w; }
else { down3 -= p1[i].w; up3 += p1[i].w; }
ans = max(ans, (wei[1] + wei[2] + xian2 + up1 + up3) * (wei[0] + wei[3] + xian4 + down1 + down3));
}
// 二、四象限
int up2 = 0, down2 = xian2, up4 = xian4, down4 = 0;
sort(p2.begin(), p2.end());
ans = max(ans, (wei[0] + wei[1] + xian1 + xian4) * (wei[2] + wei[3] + xian2 + xian3));
ans = max(ans, (wei[0] + wei[1] + xian1 + xian2) * (wei[2] + wei[3] + xian4 + xian3));
for(int i = 0; i < p2.size(); i++) {
if(p2[i].x > 0) { up4 -= p2[i].w; down4 += p2[i].w; }
else { down2 -= p2[i].w; up2 += p2[i].w; }
ans = max(ans, (wei[0] + wei[1] + xian1 + up2 + up4) * (wei[2] + wei[3] + xian3 + down2 + down4));
}
printf("%lld\n", ans);
}
return 0;
}

hdu6127的更多相关文章

  1. HDU6127 简单几何 暴力二分

    LINK 题意:给出n个点,每个点有个权值,可以和任意另外一点构成线段,值为权值积.现问过原点的直线中交所有线段的权值和的最大值,注意直线必不经过点. 思路:直线可以将点集分为两侧,此时的权值为两侧点 ...

  2. hdu6127 Hard challenge

    地址:http://acm.split.hdu.edu.cn/showproblem.php?pid=6127 题目: Hard challenge Time Limit: 4000/2000 MS ...

  3. 【极角排序】【扫描线】hdu6127 Hard challenge

    平面上n个点,每个点带权,任意两点间都有连线,连线的权值为两端点权值之积.没有两点连线过原点.让你画一条过原点直线,把平面分成两部分,使得直线穿过的连线的权值和最大. 就把点极角排序后,扫过去,一侧的 ...

  4. 2017 Multi-University Training Contest - Team 7

    HDU6121 Build a tree 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6121 题目意思:一棵 n 个点的完全 k 叉树,结点标号从 ...

随机推荐

  1. [洛谷P3413]SAC#1 - 萌数

    题目大意:求$[l,r](0\leqslant l<r< 10^{1001})$中存在长度至少为$2$的回文串的数字数 题解:数位$DP$,发现如果有回文串,若长度为偶数,一定有两个相同的 ...

  2. 理解First Chance和Second Chance避免单步调试

    原文链接地址:http://blog.csdn.net/Donjuan/article/details/3859160 在现在C++.Java..Net代码大行其道的时候,很多代码错误(Bug)都是通 ...

  3. 【BZOJ 4514】[Sdoi2016]数字配对 费用流

    利用spfa流的性质,我直接拆两半,正解分奇偶(妙),而且判断是否整除且质数我用的是暴力根号,整洁判断质数个数差一(其他非spfa流怎么做?) #include <cstdio> #inc ...

  4. EditPlus直接连接Linux服务器编辑文本文件

    填写好:描述,ip地址,用户名,密码, 然后点下面的高级选项: 然后返回上一个页面,继续 确定 OK: 然后,在主界面左侧点倒三角: 就可以选择我们之前配置的远程服务器地址,弹出提示框 点确定, 就连 ...

  5. oracle数据库cmd导出数据和导入数据

    一:前言 每次我自己来导出oracle数据的数据进行备份的时候都是要看一遍记载的语句,还别说自己敲多了,也熟练了,但是还是不是很放心,所以就记载下来吧. 二:内容 (1).最简单,最直接的导入方式(这 ...

  6. 【BZOJ4774】修路 [斯坦纳树]

    修路 Time Limit: 20 Sec  Memory Limit: 256 MB Description Input Output 仅一行一个整数表示答案. Sample Input 5 5 2 ...

  7. bzoj 1576: [Usaco2009 Jan]安全路经Travel——并查集+dijkstra

    Description Input * 第一行: 两个空格分开的数, N和M * 第2..M+1行: 三个空格分开的数a_i, b_i,和t_i Output * 第1..N-1行: 第i行包含一个数 ...

  8. [BZOJ3033]太鼓达人|欧拉图

    Description 七夕祭上,Vani牵着cl的手,在明亮的灯光和欢乐的气氛中愉快地穿行.这时,在前面忽然出现了一台太鼓达人机台,而在机台前坐着的是刚刚被精英队伍成员XLk.Poet_shy和ly ...

  9. Linux 之test expr命令

    test指令(使用指令man查询) 功能:检查文件类型,值比较. test的各种参数和使用. test EXPRESSION1 –a EXPRESSION2 当表达式1和表达式2同时为真时值为真 te ...

  10. SQLAlchemy中filter()和filter_by()有什么区别

    from:https://segmentfault.com/q/1010000000140472 filter: apply the given filtering criterion to a co ...