解题思路
我们对于国王身后的两个点来分析:
-
队列可能是这样的:
那么我们计算可得 a n s 1 = m a x ( a 0 / b 1 , a 0 ∗ a 1 / b 2 ) ; ans_1=max(a_0/b_1,a_0*a_1/b_2); ans1=max(a0/b1,a0∗a1/b2); -
队列也有可能是这样的:
那么我们计算可得 a n s 2 = m a x ( a 0 / b 2 , a 0 ∗ a 2 / b 1 ) ; ans_2=max(a_0/b_2,a_0*a_2/b_1); ans2=max(a0/b2,a0∗a2/b1);
我们来对比一下两个答案:
a
n
s
1
=
m
a
x
(
a
0
/
b
1
,
a
0
∗
a
1
/
b
2
)
;
ans_1=max(a_0/b_1,a_0*a_1/b_2);
ans1=max(a0/b1,a0∗a1/b2);
a
n
s
2
=
m
a
x
(
a
0
/
b
2
,
a
0
∗
a
2
/
b
1
)
;
ans_2=max(a_0/b_2,a_0*a_2/b_1);
ans2=max(a0/b2,a0∗a2/b1);
显然我们可以得到:
a
0
∗
a
1
/
b
2
>
a
0
/
b
2
,
a
0
∗
a
2
/
b
1
>
a
0
/
b
1
a_0*a_1/b_2>a_0/b_2,a_0*a_2/b_1>a_0/b_1
a0∗a1/b2>a0/b2,a0∗a2/b1>a0/b1
如果
a
n
s
1
<
a
n
s
2
ans_1 <ans_2
ans1<ans2,那么易得:
a
0
∗
a
1
/
b
2
<
a
0
∗
a
2
/
b
1
a_0*a_1/b_2<a_0*a_2/b_1
a0∗a1/b2<a0∗a2/b1
变形可得: a 1 ∗ b 1 < a 2 ∗ b 2 a_1*b_1<a_2*b_2 a1∗b1<a2∗b2
当 a 1 ∗ b 1 < a 2 ∗ b 2 a_1*b_1<a_2*b_2 a1∗b1<a2∗b2时,我们也能够得到 a n s 1 < a n s 2 ans_1<ans_2 ans1<ans2的结论。所以,为了 a n s ans ans取到最小值,我们需要将 a i ∗ b i a_i*b_i ai∗bi较小的放在前面…
那么我们以 a i ∗ b i a_i*b_i ai∗bi为关键字排序即可,同时,统计答案时一定不要忘了写高精度!
代码
#include<algorithm>
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
using namespace std;
int n,cnt,cnt1,cntt,ans[20000],lyx[20000],kj[20000];
struct c{
long long x,y;
}a[2000];
bool cmp(const c&a,const c&b)
{
return a.x*a.y<b.x*b.y;
}
void mul(long long x){
int s=0,g=0;
for(int i=1;i<=cnt;i++)
{
s=ans[i]*x+g;
ans[i]=s%10;
g=s/10;
}
while(g!=0)
{
ans[++cnt]=g%10;
g=g/10;
}
}
void cut(long long x){
int s=0;
memset(lyx,0,sizeof(lyx));
for(int i=cnt;i>0;i--)
{
s=s*10+ans[i];
if(s>=x)
{
lyx[i]=s/x;
s=s%x;
}
}
cnt1=cnt;
while(lyx[cnt1]==0)
{
if(cnt1 == 1)
break;
cnt1--;
}
}
void maxn(){
int flag=1;
if(cnt1>cntt)
{
for(int i=1;i<=cnt1;i++)
kj[i]=lyx[i];
cntt=cnt1;
}
else
{
for(int i=cnt1;i>0;i--)
if(lyx[i]>kj[i])
{
flag=0;
break;
}
if(flag==0)
{
for(int i=1;i<=cnt1;i++)
kj[i]=lyx[i];
}
}
}
int main(){
scanf("%d",&n);
scanf("%lld%lld",&a[0].x,&a[0].y);
for(int i=1;i<=n;i++)
scanf("%lld%lld",&a[i].x,&a[i].y);
sort(a+1,a+n+1,cmp);
ans[1]=1,cnt=1,cnt1=1,cntt=1;
for(int i=1;i<=n;i++)
{
mul(a[i-1].x);
cut(a[i].y);
maxn();
}
for(int i=cntt;i>0;i--)
printf("%d",kj[i]);
}