洛谷 P1080 国王游戏 用java写的高精 代码简短好理解

P1080 国王游戏

题目内容

https://www.luogu.com.cn/problem/P1080

思路

这道题是倾向于贪心以及高精度,所以题解的代码是用java写的
假设队列是这样的

king a 0 a_0 a0 b 0 b_0 b0
p 1 p_1 p1 a 1 a_1 a1 b 1 b_1 b1
p 2 p_2 p2 a 2 a_2 a2 b 2 b_2 b2

这个的答案就是 a n s 1 ans_1 ans1 = m a x ( max( max( a 0 b 1 \frac{a_0}{b_1} b1a0 , , , a 0 ∗ a 1 b 2 \frac{a_0 * a_1}{b_2} b2a0a1 ) ) )
另一种情况就是

king a 0 a_0 a0 b 0 b_0 b0
p 2 p_2 p2 a 2 a_2 a2 b 2 b_2 b2
p 1 p_1 p1 a 1 a_1 a1 b 1 b_1 b1

这个的答案就是 a n s 2 ans_2 ans2 = m a x ( max( max( a 0 b 2 \frac{a_0}{b_2} b2a0 , , , a 0 ∗ a 2 b 1 \frac{a_0 * a_2}{b_1} b1a0a2 ) ) )
然后把进行替换
a n s 1 ans_1 ans1 = m a x ( k 1 , k 2 ) max(k_1,k_2) max(k1,k2)
a n s 2 ans_2 ans2 = m a x ( k 3 , k 4 ) max(k_3,k_4) max(k3,k4)
通过上面式子可以看出
k 2 > k 3 k_2 > k_3 k2>k3
k 4 > k 1 k_4 > k_1 k4>k1
假设 a n s 1 < a n s 2 ans_1 < ans_2 ans1<ans2
那么可以得出
k 4 > k 2 k_4 > k_2 k4>k2
k 4 , k 2 k_4,k_2 k4,k2的具体内容带入
可以得 a 1 ∗ b 1 < a 2 ∗ b 2 a_1*b_1<a_2*b_2 a1b1<a2b2
a 1 ∗ b 1 < a 2 ∗ b 2 a_1*b_1<a_2*b_2 a1b1<a2b2也可以得出 k 4 > k 2 k_4 > k_2 k4>k2结论
所以,为了ans取最小值,我们需要把 a i ∗ b i 较 小 的 放 在 前 面 a_i*b_i较小的放在前面 aibi
这道题看题目数据范围很明显就是需要高精度
摘自
https://www.luogu.com.cn/blog/league/solution-p1080
但代码是作者本人写的,只是用别人的分析。

代码

import java.math.BigInteger;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Scanner;
public class Main {
	public static void main(String[] args) {

		Scanner cin = new Scanner(System.in);
		BigInteger [][] a = new BigInteger[1010][2];
		int n;
		BigInteger sum = new BigInteger("1");
		n = cin.nextInt();
		for(int i = 1; i <= n + 1; i ++)
		{
			a[i][0] = cin.nextBigInteger();
			a[i][1] = cin.nextBigInteger();
			sum = sum.multiply(a[i][0]);
		}
		Arrays.sort(a, 2, n + 2, new Comparator<BigInteger[]>() {
				public int compare(BigInteger []o1, BigInteger []o2) {
					BigInteger s = o1[0].multiply(o1[1]);
					BigInteger s1 = o2[0].multiply(o2[1]);
					return s.compareTo(s1);
				}
        });//排序,从小到大
		BigInteger ans = a[1][0].divide(a[2][1]);
		sum = a[1][0];
		for(int i = 2; i <= n + 1; i ++)
		{
			if(sum.divide(a[i][1]).compareTo(ans) == 1)
			{
				ans = sum.divide(a[i][1]);
			}
			sum = sum.multiply(a[i][0]);
		}
		System.out.println(ans);
		cin.close();
	}
//看完代码是不是觉得这道题很简单。
}
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值