6700. 得分(score )

Posted gmh77

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了6700. 得分(score )相关的知识,希望对你有一定的参考价值。

题目描述

技术图片
技术图片

题解

显然按a/t从大到小排序,在同一块里时间可以任意

然后按a从小到大排序,只用考虑相邻的a段(证明丢到坐标系上,找最小的正斜率),化式子发现有x/T,把段里的可能时间取最大/最小即可直接算c

code

#include <bits/stdc++.h>
#define fo(a,b,c) for (a=b; a<=c; a++)
#define fd(a,b,c) for (a=b; a>=c; a--)
#define abs(x) ((x)>0?(x):-(x))
#define min(a,b) (a<b?a:b)
#define max(a,b) (a>b?a:b)
#define E 0.000000001
#define ll long long
#define file
using namespace std;

struct type{
	double a,t,s;
	int id;
} a[200001];
double L,R,Mid,sum,Sum,c,ans,mn[200001],mx[200001],Mn,Mx,Mn2,Mx2,A,s1,s2;
int n,i,j,k,l;

bool cmp(type x,type y) {return abs(x.s-y.s)>E && x.s>y.s || abs(x.s-y.s)<=E && x.t<y.t;}
bool Cmp(type x,type y) {return x.a<y.a;}

int main()
{
	freopen("score.in","r",stdin);
	#ifdef file
	freopen("score.out","w",stdout);
	#endif
	
	scanf("%d",&n);
	fo(i,1,n) scanf("%lf",&a[i].a);
	fo(i,1,n) scanf("%lf",&a[i].t),a[i].s=a[i].a/a[i].t,sum+=a[i].t;
	sort(a+1,a+n+1,cmp);
	
	memset(mn,127,sizeof(mn));
	memset(mx,254,sizeof(mx));
	j=0;
	fo(i,1,n)
	{
		j+=(i==1 || abs(a[i].s-a[i-1].s)>E);
		a[i].id=j;
		if (mn[j]>9223372036854775807ll) mn[j]=Sum;
		Sum+=a[i].t;
		mx[j]=max(mx[j],Sum/sum);
	}
	
	sort(a+1,a+n+1,Cmp);
	c=1;
	Mn=Mn2=-1;
	fo(i,1,n)
	{
		if (Mn==-1) Mn=mn[a[i].id]+a[i].t,Mx=mx[a[i].id];
		else Mn=min(Mn,mn[a[i].id]+a[i].t),Mx=max(Mx,mx[a[i].id]);
		
		if (i==n || abs(a[i].a-a[i+1].a)>E)
		{
			if (Mn2>-1)
			{
				s1=a[i].a*Mx,s2=A*(Mn2/sum);
				if (abs(s1-s2)>E && s1>s2)
				c=min(c,(a[i].a-A)/(s1-s2));
			}
			
			Mn2=Mn,Mx2=Mx;
			Mn=-1;A=a[i].a;
		}
	}
	printf("%.11lf
",c);
	
	fclose(stdin);
	fclose(stdout);
	return 0;
}

以上是关于6700. 得分(score )的主要内容,如果未能解决你的问题,请参考以下文章

6700. 2020.06.07省选模拟得分

6700. 2020.06.07省选模拟得分

获取数组中两个得分高对象

UVa 1585 Score(得分)

Elasticsearch--搜索

(UVA)1585 --Score(得分)