打卡信奥刷题(1697)用C++实现信奥 P8244 [COCI 2013/2014 #3] KOLINJE

P8244 [COCI 2013/2014 #3] KOLINJE

题目描述

在一年一度的生猪屠宰会上,屠夫 Bajs 正在进行活动的最后一个环节——将自己那条屡获殊荣的火腿拿出一部分,分给参加活动的所有人。

今年的生猪屠宰会一共有 n n n 个人参加,其中第 i i i 个人目前已经吃了 a i a_i ai 千克火腿。Bajs 将自己的火腿按照 b 1 : b 2 : ⋯ : b n b_1:b_2:\cdots:b_n b1:b2::bn 的比例分给所有人,换句话说,令 S = ∑ j = 1 n b j S=\sum\limits_{j=1}^nb_j S=j=1nbj,则第 i i i 个人将分到总火腿重量的 b i S \dfrac{b_i}S Sbi

但是,直到现在,Bajs 也没能确定他要拿出的火腿总量,因为在给每个人分完火腿并吃完以后,现场将根据每个人吃的火腿的千克数从大到小列出一个排名表(如果有两个人吃的肉的千克数相同,则按照两个人的编号从小到大排序),并宣布本次生猪屠宰会的年度人物,即排名表的第一位。虽然 Bajs 曾多次受到他人贿赂,但是他仍旧不愿改变分配的比例,并说他很诚实并且心地善良。Bajs 是个重度强迫症患者,因此他希望排名表上的人的编号从前往后依次为 1 , 2 , ⋯   , n 1,2,\cdots,n 1,2,,n。请你帮助 Bajs 确定他要拿出的火腿总量,以满足 Bajs 的要求。

输入格式

第一行输入一个整数 n n n,表示参加生猪屠宰会的人数。
随后 n n n 行,每行输入两个整数 a i , b i a_i,b_i ai,bi,分别表示第 i i i 个人已经吃的火腿的千克数和在火腿的分配中所占的比重(具体见『题目描述』部分)。

输出格式

如果无论 Bajs 拿出多少火腿都不能满足要求,输出 -1

否则,输出一个实数 x x x,表示 Bajs 拿出的火腿千克数。你需要保证:

  • 0 ⩽ x ⩽ 1 0 7 0\leqslant x\leqslant 10^7 0x107
  • x x x 的小数点后不得超过 12 12 12 个数位。建议自行对答案四舍五入后再输出。

上面两点中若有至少一点不满足,均会被判定为 WA

如有多解,输出任意一个解即可。即你不需要保证 Bajs 拿出的火腿千克数最小

输入输出样例 #1

输入 #1

3
7 1
3 2
10 0

输出 #1

10.5

输入输出样例 #2

输入 #2

3
2 1
4 0
0 3

输出 #2

-1

输入输出样例 #3

输入 #3

5
15 4
6 7
12 5
9 6
1 7

输出 #3

87

说明/提示

【样例 1 解释】

Bajs 拿出了 10.5 10.5 10.5 千克火腿,由于分配的比例为 1 : 2 : 0 1:2:0 1:2:0,因此三个人依次分配到 3.5 3.5 3.5 千克、 7 7 7 千克和 0 0 0 千克火腿,最终三个人依次共吃了 10.5 10.5 10.5 千克、 10 10 10 千克和 10 10 10 千克火腿。这满足 Bajs 的要求。

【数据范围与限制】

对于所有数据, 2 ⩽ n ⩽ 1000 2\leqslant n\leqslant 1000 2n1000 0 ⩽ a i , b i ⩽ 1 0 6 0\leqslant a_i,b_i\leqslant 10^6 0ai,bi106

【题目来源】

本题来源自 COCI 2013-2014 CONTEST 3 T4 KOLINJE,按照原题数据配置,满分 120 120 120 分。

由 Eason_AC 翻译整理提供。

欢迎对本题 checker 提出改进意见。

C++实现

#include //万能头文件
using namespace std;
inline long long read(){//快读
	long long x=0,f=1;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
	return x*f;
}
const int N=1e3+5;
int n;
int a[N],b[N];
int da[N],db[N];
int32_t main(){
	n=read();
	long double sum=0;
	long double L=0,R=1e9;
	for(int i=1;i<=n;i++)a[i]=read(),b[i]=read(),sum+=b[i];
	for(int i=1;i<n;i++){
		da[i]=a[i]-a[i+1];
		db[i]=b[i+1]-b[i];
		if(db[i]>0){
			R=min(R,(long double)da[i]/db[i]);
		}else if(db[i]<0){
			L=max(L,(long double)da[i]/db[i]);
		}else{
			if(da[i]<0)return puts("-1"),0;
		}
	}
	if(R<L)return puts("-1"),0;
	cout<<fixed << setprecision(12) << L*sum;
	return 0;
}

打卡信奥刷题(1697)用C++实现信奥 P8244 [COCI 2013/2014 #3] KOLINJE_第1张图片

后续

接下来我会不断用C++来实现信奥比赛中的算法题、GESP考级编程题实现、白名单赛事考题实现,记录日常的编程生活、比赛心得,感兴趣的请关注,我后续将继续分享相关内容

你可能感兴趣的:(C++,c++,算法,开发语言,青少年编程,数据结构)