HDU6127 Hard challenge[计算几何]
来源:互联网 发布:淘宝交易指数 构成 编辑:程序博客网 时间:2024/05/24 00:02
Hard challenge
HDU - 6127题意:
给T组数据,每组数据有一个n,代表n个点,接下来n行,每行给出一个x和y还有val,代表每个点的位置和值。两个点连起来的值等于两点的val相乘,不存在两点同时存在于一条与原点相连的线上。问从原点处划一条直线,不与这n个点相交(即点都不能存在于这条直线上),能经过最大的边和是多少。
题解:
实际上,用直线分开两边,得到的和就是等于该线的上方的权值和乘以该线的下方的权值和。
先对这n个点进行极角排序,然后将他们分开4个象限,保存所有点的权值和,根据象限,也保存该象限的前缀和,方便后面的计算。
然后开始从第一象限的点开始扫描到第四象限,每扫描到一个点,同象限在其前面(包括它自身)的权值加起来,用双指针,在其旋转180度的象限中找到一个斜率比该点要大的点,将其与该象限剩下的点的权值加起来,还有将其顺时针90度的象限的所有点的权值也加起来,因为这些地方都是在该线的左侧。
然后枚举出来的该线的答案就是等于 当前的权值*(sum-当前的权值)。将所有点按象限都扫一次,就可以得到最大值了。
#pragma comment(linker, "/STACK:102400000,102400000")#include<iostream>#include<cstdio>#include<cstring>#include<cmath>#include<string>#include<algorithm>#include<queue>#include<stack>#include<set>#include<map>#include<vector>using namespace std;typedef long long ll;const int N=5e4+5;ll sum[5][N];vector<int>vc[5];int nx[]={0,4,1,2,3};int fan[]={0,3,4,1,2};struct point{ int x,y,val; point (int xx=0,int yy=0,int v=0):x(xx),y(yy),val(v){}}p[N];ll cross(const point &p1,const point &p2,const point &q1,const point &q2){ return (ll)(q2.y-q1.y)*(p2.x-p1.x)-(ll)(q2.x-q1.x)*(p2.y-p1.y);}bool cmp(const point &a,const point &b){ if (!a.y && !b.y && (ll)a.x*b.x<=0) return a.x>b.x; if (!a.y && a.x>=0 && b.y) return 1; if (!b.y && b.x>=0 && a.y) return 0; if ((ll)b.y*a.y<=0) return a.y>b.y; point one; one.y=one.x=0; return cross(one,a,one,b)>0 || (!cross(one,a,one,b) && a.x<b.x);}bool check(const point &a,const point &b){ point np(-a.x,-a.y); return !cmp(np,b);}void push(int id,int i,int val){ vc[id].push_back(i); sum[id][vc[id].size()]=sum[id][vc[id].size()-1]+val;}int main(){int T;scanf("%d",&T);while (T--){ int n; scanf("%d",&n); for (int i=0 ; i<n ; ++i) scanf("%d%d%d",&p[i].x,&p[i].y,&p[i].val); sort(p,p+n,cmp); for (int i=0 ; i<=4 ; ++i) { vc[i].clear(); for (int j=0 ; j<=n ; ++j) sum[i][j]=0; } ll s=0; for (int i=0 ; i<n ; ++i) { if (p[i].x>=0 && p[i].y>=0) push(1,i,p[i].val); else if (p[i].x<0 && p[i].y>=0) push(2,i,p[i].val); else if (p[i].x<0 && p[i].y<0) push(3,i,p[i].val); else push(4,i,p[i].val); s+=p[i].val; } ll mx=0; for (int i=1 ; i<=4 ; ++i) { if (!vc[i].size()) continue; for (int j=0,k=0 ; j<vc[i].size() ; ++j) { ll tmp=sum[nx[i]][vc[nx[i]].size()]+sum[i][j+1]; while (k<vc[fan[i]].size() && check(p[vc[i][j]],p[vc[fan[i]][k]])) ++k; tmp+=sum[fan[i]][vc[fan[i]].size()]-sum[fan[i]][k]; mx=max(tmp*(s-tmp),mx); } } printf("%lld\n",mx);}return 0;}/*104-5 2 100-2 -3 100100000000 1000000000 10100000000 999999999 921 1 11 -1 131 1 11 -1 10-1 0 10042 1 10-4 -1 20-3 -4 30-2 -5 403-1 2 103 -1 201 -5 30*/
阅读全文
0 0
- HDU6127 Hard challenge[计算几何]
- HDU6127 Hard challenge【几何】
- hdu6127 Hard challenge 2017多校第七场1008 计算几何 极角排序+双指针
- hdu6127 Hard challenge
- HDU6127-Hard challenge
- hdu6127 Hard challenge
- Hard challenge(HDU6127)
- HDU6127-Hard challenge
- HDU6127-Hard challenge
- HDU6127-Hard challenge
- Hard challenge(hdu6127)
- HDU6217 Hard challenge(计算几何)
- HDU 6127 Hard challenge【计算几何】
- hdu 6127 Hard challenge(计算几何)
- (计算几何)HDU 6127 Hard challenge
- HDU 6127-Hard challenge(计算几何)
- HDU 6127 Hard challenge(计算几何)
- HDU6127 Hard challenge 极角排序|暴力
- Erlang基础之整数
- ACdream
- WordCount计数--第一个MapReduce程序
- EACCES: permission denied, mkdir '/home/错误的解决方法
- 牛客网:数据库sql实战
- HDU6127 Hard challenge[计算几何]
- C++ dlib Caffe 人脸裁剪与预测
- Cannot get property 'compileSdkVersion' on extra properties extension as it does not exist问题解决
- tomcat9.0安装jsp虚拟目录配置
- (HDU
- python 统计文件应用实例
- HDU 6127 Hard challenge 计算几何 极角排序
- .NET MVC Scripts.Render 上下文不存在问题解决方法
- Qt:基于widget方式的窗口阴影边框的实现