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;

const long double pi=3.14159265358979323846264338327950288L;
const long double eps=1e-15;

struct point
{
    int x,y;
    LL val;
    long double j;
    bool operator <(const point rhs)
    {
        return j<rhs.j;
    }
}p[100005];

int n;
LL s[100005];

LL sum(int l,int r)
{
//    if(l>r) puts("========================");
    return s[r]-s[l]+p[l].val;
}

int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        memset(s,0,sizeof(s));
        LL ans=0;
        scanf("%d",&n);
        for(int i=0;i<n;i++)
        {
            scanf("%d%d%lld",&p[i].x,&p[i].y,&p[i].val);
            p[i].j=atan2l(p[i].y,p[i].x);
        }
        sort(p,p+n);
        for(int i=0;i<n;i++) p[i+n]=p[i],p[i+n].j+=2*pi;
        s[0]=p[0].val;
        for(int i=1;i<2*n;i++) s[i]=s[i-1]+p[i].val;
        for(int l=0,r=0;l<n;l++)    //使用双指针 l,r
        {
            while(p[r+1].j<p[l].j+pi) r++;
            LL v1=sum(l,r);
            LL v2=s[n-1]-v1;
            ans=max(ans,v1*v2);
        }
        printf("%lld\n",ans);
    }
}
时间: 2024-12-18 18:22:08

hdu 6127 : Hard challenge (2017 多校第七场 1008)(计算几何)的相关文章

2014多校第七场1005 || HDU 4939 Stupid Tower Defense (DP)

题目链接 题意 :长度n单位,从头走到尾,经过每个单位长度需要花费t秒,有三种塔: 红塔 :经过该塔所在单位时,每秒会受到x点伤害. 绿塔 : 经过该塔所在单位之后的每个单位长度时每秒都会经受y点伤害. 蓝塔 : 经过该塔所在单位之后,再走每个单位长度的时候时间会变成t+z. 思路 : 官方题解 : 1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #define LL long long

2014多校第七场1003 || HDU 4937 Lucky Number

题目链接 题意 : 给定一个十进制n,让你转化成某个进制的数,让这个数只包含3 4 5 6这些数字,这个进制就成为n的幸运数字,输出有多少幸运数字,例如19,5进制表示是34,所以5是19的一个幸运数. 思路 : 以下思路有这里提供 先考虑特殊情况,所情况下会有无穷个?只有n=3,4,5,6的时候,因为这几个数在大于n的进制下都是他本身..注意特殊情况不包括33,343这些(我一开始就死在这里了,wa了三次).因为33在34进制下就不是33了(类似于10在16进制下就是A了). 我们知道n=a0

多校第七场 DP+map模拟

HDU 4939 Stupid Tower Defense DP 推一下. #include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<map> #include<queue> #include<stack> #include<vector> #include<ctype.h> #include<

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

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

2017多校第10场 HDU 6172 Array Challenge 猜公式,矩阵幂

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6172 题意:如题. 解法: #include <bits/stdc++.h> using namespace std; typedef long long LL; const LL mod = 1e9+7; struct Matrix{ LL a[3][3]; void set1(){ memset(a, 0, sizeof(a)); } void set2(){ memset(a, 0, siz

2017多校第8场 HDU 6143 Killer Names 容斥,组合计数

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6143 题意:m种颜色需要为两段长度为n的格子染色,且这两段之间不能出现相同的颜色,问总共有多少种情况. 解法:枚举要为这两段分配的颜色数目分别为 i,j ,则在第一段总共有 C(m,i) 种选取方案,在第二段总共有 C(m?i,j) 种选取方案.而在每段内部,我们设 F(n,x) 为长度为 n 的格子使用 x 种颜色(等于 x )染色的方案数.则根据容斥原理 F(n,x)=x^n?C(x,1)*(x

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;

2017多校第4场 HDU 6078 Wavel Sequence DP

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6078 题意:求两个序列的公共波形子序列的个数. 解法: 类似于最长公共上升子序列,对于每个i,只考虑存在j使得a[i]==b[j]的情况. dp[i][j][0]表示以a[i]和b[j]为公共序列结尾且为波谷的情况总和. dp[i][j][1]则表示波峰的情况总和. S[i][j][0]表示sum(dp[k][j][0] | 1<=k<=j-1). S[i][j][1]则表示sum(dp[k][j

2017多校第7场 HDU 6129 Just do it 找规律

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6129 题意:求a序列后m次xor前缀和 解法: 手动对1位置对每个位置的贡献打表发现 第一次 贡献为 1 1 1 1 1 1 1 1 1 1 1 第二次 贡献为 1 0 1 0 1 0 1 0 1 0 1 0 第四次 贡献为 1 3个0 1 3个0 1 3个0 1 3个0 第八次 贡献为 1 7个0 1 7个0 1 7个0 1 7个0 ... 这是比赛之后才知道的,看着比赛的时候通过了200+人,被