国王游戏
思路:就是按照 a i b i a_ib_i aibi 的大小从小到大排序
证明:我们不妨设两个人分别写了 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_1b_1>a_2b_2 a1b1>a2b2 则有 a 2 b 1 = b 2 a 1 \tfrac{a_2}{b_1}=\tfrac{b_2}{a_1} b1a2=a1b2
所以有一下两种情况
- 1在2的前面
- 1在2的后面
设在设在 1 , 2 1,2 1,2 之前所有人左手乘积为 k k k ,那么对于第一种情况,我们的答案就是
a n s 1 = max ( k b 1 , k a 1 b 2 ) = k ⋅ max ( 1 b 1 , a 1 b 2 ) \begin{matrix}ans_1&=&\max(\frac{k}{b_1},\frac{ka_1}{b_2})\ &=& k\cdot \max(\frac{1}{b_1},\frac{a_1}{b_2})\end{matrix} ans1=max(b1k,b2ka1) =k⋅max(b11,b2a1)
∵
a
2
b
1
<
a
1
b
2
,
a
2
>
1
\because \frac{a_2}{b_1} < \frac{a_1}{b_2},a_2>1
∵b1a2<b2a1,a2>1
∴
1
b
1
≤
a
2
b
1
<
a
1
b
2
\therefore \frac{1}{b_1} \leq \frac{a_2}{b_1} < \frac{a_1}{b_2}
∴b11≤b1a2<b2a1
∴ a n s 1 = k × a 1 b 2 \therefore ans_1=\frac{k \times a_1}{b_2} ∴ans1=b2k×a1
对于第二种,答案就是
a n s 2 = m a x ( k b 2 , k × a 2 b 1 ) ans_2=max(\frac{k}{b_2},\frac{k \times a_2}{b_1}) ans2=max(b2k,b1k×a2)
{ ∵ a 1 > 1 ∴ k × a 1 b 2 ≥ k b 2 ∵ a 2 b 1 < a 1 b 2 ∴ k × a 1 b 2 > k × a 2 b 1 \left\{\begin{matrix} \because a_1>1 \\ \therefore \frac{k \times a_1}{b_2} \ge \frac{k}{b_2}\\ \because \frac{a_2}{b_1}<\frac{a_1}{b_2} \\ \therefore \frac{k \times a_1}{b_2}>\frac{k \times a_2}{b_1}\end{matrix}\right. ⎩ ⎨ ⎧∵a1>1∴b2k×a1≥b2k∵b1a2<b2a1∴b2k×a1>b1k×a2
∴ a n s 1 ≥ a n s 2 \therefore ans_1 \ge ans_2 ∴ans1≥ans2
所以按照 按照 a i b i a_ib_i aibi 的大小从小到大排序的方法没有问题。
细节:注意高精度
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int N;
int a[1005],b[1005],ka,kb;
int ans[20000],t[20000],lena,lent,tt[20000],t2[20000],len;
void _qst_ab(int l,int r)
{
int i=l,j=r,ma=a[(i+j)>>1],mb=b[(i+j)>>1];
while(i<=j)
{
while(a[i]*b[i]<ma*mb) i++;
while(a[j]*b[j]>ma*mb) j--;
if(i<=j)
{
swap(a[i],a[j]);
swap(b[i],b[j]);
i++;j--;
}
}
if(l<j) _qst_ab(l,j);
if(i<r) _qst_ab(i,r);
}
void _init()
{
scanf("%d%d%d",&N,&a[0],&b[0]);
for(int i=1;i<=N;i++)
scanf("%d%d",&a[i],&b[i]);
}
void _get_t(int Left,int Right)
{
for(int i=1;i<=lent;i++)
{
tt[i]+=t[i]*Left;
tt[i+1]+=tt[i]/10;
tt[i]%=10;
}
lent++;
while(tt[lent]>=10)
{
tt[lent+1]=tt[lent]/10;
tt[lent]%=10;
lent++;
}
while(lent>1&&tt[lent]==0) lent--;
len=lent;
memcpy(t,tt,sizeof(tt));
memset(tt,0,sizeof(tt));
for(int i=1,j=len;i<=len;i++,j--)
t2[i]=t[j];
int x=0,y=0;
for(int i=1;i<=len;i++)
{
y=x*10+t2[i];
tt[i]=y/Right;
x=y%Right;
}
x=1;
while(x<len&&tt[x]==0) x++;
memset(t2,0,sizeof(t2));
for(int i=1,j=x;j<=len;i++,j++)
t2[i]=tt[j];
memcpy(tt,t2,sizeof(t2));
len=len+1-x;
}
bool _cmp()
{
if(len>lena) return true;
if(len<lena) return false;
for(int i=1;i<=len;i++)
{
if(ans[i]<tt[i]) return true;
if(ans[i]>tt[i]) return false;
}
return false;
}
void _solve()
{
_qst_ab(1,N);
t[1]=1;lent=1;
for(int i=1;i<=N;i++)
{
memset(tt,0,sizeof(tt));
len=0;
_get_t(a[i-1],b[i]);
if(_cmp())
{
memcpy(ans,tt,sizeof(tt));
lena=len;
}
}
for(int i=1;i<=lena;i++)
printf("%d",ans[i]);
printf("\n");
}
int main()
{
_init();
_solve();
return 0;
}