【YBTOJ】国王游戏

在这里插入图片描述

思路:

我们首先考虑,怎样进行贪心排序

我们设一个si表示前i个a的相乘
我们首先考虑排序交换前,第i个上的值是 s i − 1 / b i s_{i-1}/b_i si1/bi,第i+1个是 s i − 1 ∗ a i / b i + 1 s_{i-1}*a_i/b_{i+1} si1ai/bi+1
交换后各为 s i − 1 / b i + 1 s_{i-1}/b_{i+1} si1/bi+1 s i − 1 ∗ a i + 1 / b i s_{i-1}*a_{i+1}/b_{i} si1ai+1/bi
那么我们发现 s i − 1 / b i s_{i-1}/b_i si1/bi< s i − 1 ∗ a i + 1 / b i s_{i-1}*a_{i+1}/b_{i} si1ai+1/bi
那么我们只用比较 s i − 1 ∗ a i + 1 / b i s_{i-1}*a_{i+1}/b_{i} si1ai+1/bi s i − 1 ∗ a i / b i + 1 s_{i-1}*a_i/b_{i+1} si1ai/bi+1就可以了
通过化简,得:
a i ∗ b i < a i + 1 ∗ b i + 1 a_i*b_i<a_{i+1}*b_{i+1} aibi<ai+1bi+1
由此可见,对a*b进行关键字排序就可以了

c o d e code code

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
long long n, a1, b;
long long sum[50001], k[50001], ans[50001];
struct node
{
	long long x, y;
}a[100010];
bool cmp(node x, node y)
{
	return x.x*x.y<y.x*y.y; 
}
void times(long long b)
{
	long long g=0;
	for(long long i=1; i<=50000; i++)
	{
		sum[i]=sum[i]*b+g;
		g=sum[i]/10;
		sum[i]%=10;
	}
}
void fz()
{
	for(long long i=1; i<=50000; i++)
		k[i]=ans[i];
}
void fc(long long b)
{
	long long i=50000;
	memset(ans, 0, sizeof(ans));
	while(sum[i]==0)
		i--;
	long long ys=0;
	for(; i>=1; i--)
	{
		ys=ys*10+sum[i];
		ans[i]=ys/b;
		ys=ys%b;
	}
	long long kw=50000;
	while(k[kw]==0)kw--;
	long long answ=50000;
	while(ans[answ]==0)answ--;
	if(kw>answ)
		return;
	else if(answ>kw)
		fz();
	else
	{
		for(long long i=kw; i>=1; i--)
			if(ans[i]>k[i])
				fz();
			else if(ans[i]<k[i])
				return;
	}
}
int main()
{
	scanf("%lld", &n);
	scanf("%lld%lld", &a1, &b);
	for(long long i=1; i<=n; i++)
		scanf("%lld%lld", &a[i].x, &a[i].y);
	sort(a+1, a+1+n, cmp);
	long long j=0;
	while(a1!=0)
	{
		sum[++j]=a1%10;
		a1=a1/10;
	}
	for(long long i=1; i<=n; i++)
	{
		fc(a[i].y);
		times(a[i].x);
	}
	long long i=50000;
	while(k[i]==0)i--;
	for(; i>=1; i--)
		printf("%lld", k[i]);
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值