解题报告:HDU_6127:Hard challenge (极角排序)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_32570675/article/details/77366131

题目链接

题意及官方题解:


补充:

我是以到x负半轴的弧度进行排序,然后扫过(0~PI)的弧度,中间每扫过一个点都要可能更新答案


代码:

#include<bits/stdc++.h>

const double pi=acos(-1.0);
using namespace std;

class point
{
public:
      int x,y,v;
      double radiu;

public:
   point(){};
   point (int a,int b)
   {
      x=a;
      y=b;
   }
}p[100010];
bool cmp(point a,point b){
   return a.radiu<b.radiu;
}

double calc(int x,int y){
      if (x<0 && y>0)      return atan((double)1.0*y/((double)-1.0*x));
      else if (x==0 && y>0)return (double)2.0*pi/4.0;
      else if (x>0 && y>0) return (double)2.0*pi/4.0+atan((double)1.0*x/((double)1.0*y));
      else if (x>0 && y==0)return (double)2.0*pi/2.0;
      else if (x>0 && y<0) return (double)2.0*pi/2.0+atan((double)(-1.0*y)/(double)(1.0*x));
      else if (x==0 && y<0)return (double)2.0*pi*((double)3.0/4.0);
      else if (x<0 && y<0) return (double)2.0*pi*((double)3.0/4.0)+atan(((double)-1.0*x)/((double)-1.0*y));
      else if (x<0 && y==0)return (double)0;
}

int main()
{
   //freopen("1008.in","r",stdin);
   //freopen("my_1008.out","w",stdout);
   int T,n;
   scanf("%d",&T);
   while (T--)
   {
      long long sum = 0 , ss = 0 , ans = 0;
      scanf("%d",&n);
      for (int i=0 ; i<n ; i++)
      {
         scanf("%d%d%d",&p[i].x,&p[i].y,&p[i].v);
         p[i].radiu=calc(p[i].x,p[i].y);
         sum += p[i].v;
      }sort(p,p+n,cmp) ;
      int s = 0 ,e = 0 ;
      while(s<n&&p[s].radiu<=pi){
         double ed = pi + p[s].radiu;
         while(e<n&&p[e].radiu<=ed){
            ss += p[e++].v ;
            ans = max(ans,ss*(sum-ss));
         }ss -= p[s++].v;
         ans = max(ans,ss*(sum-ss));
      }printf("%lld\n",ans);
   }
   return 0;
}



阅读更多

没有更多推荐了,返回首页