洛谷P1080 国王游戏

超级会玩的国王

题目描述

恰逢 H国国庆,国王邀请n 位大臣来玩一个有奖游戏。首先,他让每个大臣在左、右手上面分别写下一个整数,国王自己也在左、右手上各写一个整数。然后,让这 n位大臣排成一排,国王站在队伍的最前面。排好队后,所有的大臣都会获得国王奖赏的若干金币,每位大臣获得的金币数分别是:排在该大臣前面的所有人的左手上的数的乘积除以他自己右手上的数,然后向下取整得到的结果。

国王不希望某一个大臣获得特别多的奖赏,所以他想请你帮他重新安排一下队伍的顺序,使得获得奖赏最多的大臣,所获奖赏尽可能的少。注意,国王的位置始终在队伍的最前面。

输入格式

第一行包含一个整数n,表示大臣的人数。

第二行包含两个整数 a和 b,之间用一个空格隔开,分别表示国王左手和右手上的整数。

接下来 n行,每行包含两个整数a 和 b,之间用一个空格隔开,分别表示每个大臣左手和右手上的整数。

输出格式

一个整数,表示重新排列后的队伍中获奖赏最多的大臣所获得的金币数。

输入输出样例

输入 #1复制

1
2
3
4
5
3 
1 1
2 3
7 4
4 6

输出 #1复制

1
2

说明/提示

【输入输出样例说明】

按1、2、3 这样排列队伍,获得奖赏最多的大臣所获得金币数为 2;

按 1、3、2这样排列队伍,获得奖赏最多的大臣所获得金币数为2;

按 2、1、3 这样排列队伍,获得奖赏最多的大臣所获得金币数为 2;

按2、3、1这样排列队伍,获得奖赏最多的大臣所获得金币数为9;

按 3、1、2这样排列队伍,获得奖赏最多的大臣所获得金币数为 2;

按3、2、1 这样排列队伍,获得奖赏最多的大臣所获得金币数为 9。

因此,奖赏最多的大臣最少获得 2个金币,答案输出 2。

【数据范围】

对于 20%的数据,有 1≤ n≤ 10,0 < a,b < 8;

对于 40%的数据,有1≤ n≤20,0 < a,b < 8;

对于 60%的数据,有 1≤ n≤100;

对于 60%的数据,保证答案不超过 10^9;

对于 100%的数据,有 1 ≤ n ≤1,000,0 < a,b < 10000。

思路

本题的代码并不难写,主要是思路的分析,分析如下。

我们对于国王身后的两个点来分析

队列可能是这样的:

* Left Right
king: a0 b0
p1 a1 b1
p2 a2 b2

那么我们计算可得

队列也有可能是这样的

* Left Right
king: a0 b0
p2 a2 b2
p1 a1 b1

那么我们计算可得

我们来对比一下两个答案:

显然我们可以得到:

如果

那么易得:

变形可得:

时,我们也能够得到

的结论

所以,为了ans取到最小值,我们需要将

较小的放在前面

那么我们以

为关键字排序即可

统计答案时一定不要忘了写高精度!

AC code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
#include<bits/stdc++.h>
using namespace std;
int n,a,b;
int sum[100000]={0,1},ans[100000],m[100000],lens=1,lend=1,lenm=1;
struct stt
{
int l,r;
int lr;
}st[10000000];
bool cmp(stt p,stt q)
{
return p.lr<q.lr;
}
void times(long long x)//高精度乘
{
int t=0;
for(int i=1;i<=lens;i++){
sum[i]*=x;
}
for(int i=1;i<=lens;i++){
t+=sum[i];
sum[i]=t%10;
t/=10;
}
while(t!=0){
lens++;
sum[lens]=t%10;
t/=10;
}
}
void division(long long x)//高精度除
{
int t=0;
lend=lens;
memset(ans,0,sizeof(ans));
for(int i=lend;i>=1;i--){
t*=10;
t+=sum[i];
if(t>=x){
ans[i]=t/x;
t%=x;
}
}
while(ans[lend]==0){
if(lend==1)
break;
lend--;
}
}
void solve()
{
if(lenm<lend){
for(int i=1;i<=lend;i++){
m[i]=ans[i];
}
lenm=lend;
}
else if(lenm==lend){
for(int i=lend;i>=1;i--){
if(m[i]<ans[i]){
for(int j=1;j<=lend;j++)
m[j]=ans[j];
lenm=lend;
break;
}
}
}
}
int main()
{
cin>>n;
for(int i=0;i<=n;i++)
{
cin>>st[i].l>>st[i].r;
st[i].lr=st[i].l*st[i].r;
}
sort(st+1,st+1+n,cmp);
for(int i=1;i<=n;i++)
{
times(st[i-1].l);
division(st[i].r);
solve();
}
for(int i=lenm;i>=1;i--)
printf("%d",m[i]);
return 0;
}
打赏
  • 版权声明: 本博客所有文章除特别声明外,均采用 Apache License 2.0 许可协议。转载请注明出处!
  • © 2020 Super Monkey
  • Powered by Hexo Theme Ayer
  • PV: UV:

请我喝杯咖啡吧~

支付宝
微信