HDU 6127 Hard challenge (极角排序+二分, 2017 Multi-Univ Training Contest 7)
来源:互联网 发布:淘宝助理导出数据包 编辑:程序博客网 时间:2024/06/05 08:49
Problem
Problem Link
There are n points on the plane, and the ith points has a value
Idea
在已知直线将坐标系分割为两部分时,求任意左上部分点到右下部分点的线段价值和,可以等效地看作是
显然由于通过过原点直线分割图形,可以将所有点按照极角排序。通过枚举点 i (x, y) ,假设直线恰好通过点 i ,二分获取最大的在极角排序中小于点 i 关于原点对称点 (-x, -y) (题目保证不会有任意两点的连线过原点)。则直接可以求当前划分所产生的价值和(当然,需要区分 i 点在左上或右下的情况,显然 i 过直线是不会产生价值,即总价值缩水,微偏移直线的斜率即可最大化当前枚举情况的最优。)
当然,不使用二分,利用双指针的做法来获取左上点与右下点的分界也可。
HINT: 由于此题的坐标取值较大,可能出现中间过程爆 int 的可能,最好将坐标 x , y 取 long long 。:joy: 没注意在这个问题上 WA 了两发。
Code
#include<bits/stdc++.h>using namespace std;const int N = 50000 + 10;int T, n, pre[N];struct point { long long x, y, val;} p[N], ori, np;double cross(const point &p1, const point &p2, const point &q1, const point &q2) { return (q2.y - q1.y)*(p2.x - p1.x) - (q2.x - q1.x)*(p2.y - p1.y); }bool cmp(const point &a, const point &b) { if (a.y == 0 && b.y == 0 && a.x*b.x <= 0)return a.x>b.x; if (a.y == 0 && a.x >= 0 && b.y != 0)return true; if (b.y == 0 && b.x >= 0 && a.y != 0)return false; if (b.y*a.y <= 0)return a.y>b.y; return cross(ori,a,ori,b) > 0 || (cross(ori,a,ori,b) == 0 && a.x < b.x); }bool jug(int idx, int mid) { np.x = -p[idx].x; np.y = -p[idx].y; if(cmp(np, p[mid]) == true) return false; return true;}int bs(int idx, int l, int r, int ans) { int mid; while(l <= r) { mid = (l+r) / 2; if(jug(idx, mid)) { l = mid + 1, ans = mid; } else { r = mid - 1; } } return ans;}long long calc(long long part) { return part * (pre[n] - part);}long long solve(){ long long ans = 0; for(int i=1, lft, rgt;i<=n;i++) { if(p[i].y < 0) { lft = bs(i, 1, i-1, 0); ans = max(ans, calc(pre[i] - pre[lft])); ans = max(ans, calc(pre[i-1] - pre[lft])); } else { rgt = bs(i, i+1, n, i); ans = max(ans, calc(pre[rgt] - pre[i])); ans = max(ans, calc(pre[rgt] - pre[i-1])); } } return ans;}int main(){ ori.x = ori.y = 0; scanf("%d", &T); while(T-- && scanf("%d", &n)!=EOF) { for(int i=1;i<=n;i++) scanf("%lld %lld %lld", &p[i].x, &p[i].y, &p[i].val); sort(p+1, p+n+1, cmp); for(int i=1;i<=n;i++) { pre[i] = pre[i-1] + p[i].val; } printf("%lld\n", solve()); }}
- HDU 6127 Hard challenge (极角排序+二分, 2017 Multi-Univ Training Contest 7)
- HDU 6127 Hard challenge(思维+计算几何)——2017 Multi-University Training Contest
- HDU 6070 Dirt Ratio (二分+线段树, 2017 Multi-Univ Training Contest 4)
- 2017 Multi-University Training Contest 7:Hard challenge
- HDU 6124 Euler theorem (2017 Multi-Univ Training Contest 7)
- HDU 6121 Build a tree (递归+特判, 2017 Multi-Univ Training Contest 7)
- HDU 6125 Free from square (状压 dp , 2017 Multi-Univ Training Contest 7)
- HDU 6128 Inverse of sum (数论, 2017 Multi-Univ Training Contest 7)
- HDU 6058 Kanade's sum (链表, 2017 Multi-Univ Training Contest 3)
- HDU 6065 RXD, tree and sequence (LCA, 2017 Multi-Univ Training Contest 3)
- HDU 6071 Lazy Running (Dijstra, 2017 Multi-Univ Training Contest 4)
- HDU 6078 Wavel Sequence (dp + 树状数组, 2017 Multi-Univ Training Contest 4)
- HDU 6069 Counting Divisors (2017 Multi-Univ Training Contest 4)
- HDU 6073 Matching In Multiplication (拓扑+DFS, 2017 Multi-Univ Training Contest 4)
- HDU 6046 hash (HASH, 2017 Multi-Univ Training Contest 2)
- HDU 6074 Phone Call (LCA+并查集, 2017 Multi-Univ Training Contest 4)
- HDU 6076 Security Check (DP, 2017 Multi-Univ Training Contest 4)
- HDU 6085 Rikka with Candies (bitset, 2017 Multi-Univ Training Contest 5)
- qduoj codeforces 山东省第八届acm省赛K题 CF (排序+01背包)
- BZOJ 4916 神犇和蒟蒻(杜教筛)
- 可以直接在QQ上直接提取图片的文字啦
- 最大公约数(最小公倍数)
- iOS之NSAttributedString属性值
- HDU 6127 Hard challenge (极角排序+二分, 2017 Multi-Univ Training Contest 7)
- HDU 2222:Keywords Search(AC自动机入门题)
- 安装loadrunner11的时候提示'命令行选项语法错误。键入命令 / ?’ 怎么办
- Android 与 设计模式(2)——工厂模式
- JZOJ1263. 巴比伦 (2017.8B组)
- Nginx
- Path Sum III
- 创建session学习-request.getSession()
- substring的参数问题