HDU 6127 Hard challenge(几何)
来源:互联网 发布:什么叫知世故而不世故 编辑:程序博客网 时间:2024/06/07 11:55
【题目链接】hdu-6127
【题意】平面直角坐标系上有n个整点,第i个点有一个点权v,坐标为(xi,yi),其中不存在任意两点连成的直线经过原点。这些整点两两之间连有一条线段,线段的权值为其两端点的权值之积。你需要作一条过原点而不过任意一个给定整点的直线,使得和这条直线相交的线段的权值和最大。
【样例】
Sample Input
221 1 11 -1 131 1 11 -1 10-1 0 100
Sample Output
11100
【分析】
首先,按角度分块之后,可以知道每块里任意取线段,结果是一样的。因此只要每次做原点到某一个输入点的线段,将输入点视作在某一侧就行了。
bestcoder题解是这样说的:对于一条直线,线段权值和实际上就等于其两边点权和的乘积,所以把所有点按极角排个序,然后扫一圈就好了。
其中,“线段权值和实际上就等于其两边点权和的乘积“这句话是此题解法的核心,将对所有线的处理转化为了对点的处理,时间复杂度立刻降到合理范围。再加上按极角排序,所以每次更新两侧的点不需要重新遍历一遍所有点,稍微处理上一次的数据就可以得到新的结果。
我的做法是:将点按极角排序后,对于每个点,设极角为c,每次将极角>=c&&极角-c<π的点的值加到L,将剩余点的值加入R,每次记录L范围外的下一个点为flg。当每次更新时,从L中减去上一个点的值,然后从点flg开始,不断加入符合条件的值,并更新flg。要注意flg会从n转回0,这里要处理一下。
题解真是说的一点都不清楚,我说的也一点都不清楚= =
【代码】
#include<cstdio>#include<iostream>#include<algorithm>#include<cstring>#include<cmath>using namespace std;#define maxn 50005#define pai 3.141592653int n;long long sum,ans,l,r,flg;struct node{ int x,y,v; double c;};node a[maxn];bool cmp(node a,node b){ return a.c<b.c;}double calc(int x,int y){//计算极角 double c; int ax=abs(x),ay=abs(y); if(x>=0&&y>=0){ if(x==0) c=pai/2; else c=atan(ay*1.0/ax); } else if(x<0&&y>=0) c=pai-atan(ay*1.0/ax); else if(x<=0&&y<0){ if(x==0) c=1.5*pai; else c=pai+atan(ay*1.0/ax); } else if(x>0&&y<0) c=2*pai-atan(ay*1.0/ax); return c;}void pre(){ double c=a[0].c; for(int i=0;i<n; i++){ if(a[i].c-c>pai){ flg=i; break; } if(a[i].c>=c) l+=a[i].v; } r=sum-l; ans=max(ans,l*r);}int main(){ int T; scanf("%d",&T); while(T--){ scanf("%d",&n); sum=0,ans=0,l=0,r=0,flg=n-1; for(int i=0;i<n;i++){ scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].v); sum+=a[i].v; a[i].c=calc(a[i].x,a[i].y); } sort(a,a+n,cmp); pre();//扫一遍,处理出两侧点权和 double c,m; for(int i=1;i<n;i++){ c=a[i].c; l-=a[i-1].v; for(int j=flg;j<=2*n;j++){ if(j>=n) m=a[j-n].c+2*pai;//* else m=a[j].c; if(m-c>=pai) break; if(m-c<pai){ if(j>=n) l+=a[j-n].v;//* else l+=a[j].v; flg++; } } r=sum-l; ans=max(ans,l*r); } cout<<ans<<endl; } return 0;}
阅读全文
0 0
- HDU 6127 Hard challenge (几何)
- HDU 6127 Hard challenge(几何)
- HDU 6127 Hard challenge【几何】
- HDU 6127 Hard challenge(几何)
- HDU 6127 Hard challenge【计算几何】
- hdu 6127 Hard challenge(计算几何)
- (计算几何)HDU 6127 Hard challenge
- HDU 6127-Hard challenge(计算几何)
- HDU 6127 Hard challenge(计算几何)
- hdu Hard challenge (几何题)
- HDU 6127 Hard challenge(几何 多校第七场)
- hdu 6127 Hard challenge (计算几何——斜率排序)
- HDU 6127 Hard challenge 计算几何 极角排序
- HDU 6127 Hard challenge【计算机几何】【思维题】
- HDU 6127 Hard challenge
- hdu 6127 Hard challenge
- hdu--6127--Hard challenge
- HDU 6127 Hard challenge
- 多表操作相关问题
- Dockerfile使用方法
- HALLO
- String StringBuffer StringBuilder 三者的区别
- C Primer Plus 第四章
- HDU 6127 Hard challenge(几何)
- 【程序实例】VC++ 6.0 C++ 简单的Win32程序怎么阻止用户关闭程序
- Android SystemServer启动流程源码解析
- Android--签名制作
- Java对象序列化和反序列化
- 数据库为什么要分库分表
- js file上传图片并显示出来
- Graph’s Cycle Component
- Python安装nltk以及里面一些包的使用