恰逢 H 国国庆,国王邀请 n 位大臣来玩一个有奖游戏。首先,他让每个大臣在左、右手上面分别写下一个整数,国王自己也在左、右手上各写一个整数。然后,让这 n 位大臣排成一排,国王站在队伍的最前面。排好队后,所有的大臣都会获得国王奖赏的若干金币,每位大臣获得的金币数分别是:排在该大臣前面的所有人的左手上的数的乘积除以他自己右手上的数,然后向下取整得到的结果。
国王不希望某一个大臣获得特别多的奖赏,所以他想请你帮他重新安排一下队伍的顺序,使得获得奖赏最多的大臣,所获奖赏尽可能的少。注意,国王的位置始终在队伍的最前面。
输入描述:
第一行包含一个整数 n ,表示大臣的人数。
第二行包含两个整数 a 和 b ,之间用一个空格隔开,分别表示国王左手和右手上的整数。
接下来 n 行,每行包含两个整数 a 和 b ,之间用一个空格隔开,分别表示每个大臣左手和右手上的整数。
输出描述:
一个整数,表示重新排列后的队伍中获奖赏最多的大臣所获得的金币数。
贪心:按左右手乘积从小到大排序
具体证明过程略,主要是写一下用vector的高精度乘除法
代码:
#include<bits/stdc++.h>
#define ll long long
using namespace std;
struct peo{
int a,b;
int all;
}p[1005];
bool cmp(peo x,peo y)
{
return x.all<y.all;
}
vector<int> div(vector<int> s,int k)
{
vector<int>c;int t=0;
for(int i=s.size()-1;i>=0;--i)
{
t=t*10+s[i];
c.push_back(t/k);
t%=k;
}
reverse(c.begin(),c.end());
while(c.back()==0&&c.size()) c.pop_back();
for(int i=0;i<s.size();++i)
{
// cout<<c[i];
}
return c;
}
vector<int> mul(vector<int> s,int k)
{
vector<int>c;int t=0;
for(int i=0;i<s.size();++i)
{
t=t+s[i]*k;
c.push_back(t%10);
t/=10;
}
while(t)
{
c.push_back(t%10);
t/=10;
}
while(c.back()==0&&c.size()) c.pop_back();
return c;
}
vector<int> Max(vector<int>maxn,vector<int>t)
{
if(maxn.size()>t.size()) return maxn;
else if(maxn.size()<t.size()) return t;
else
{
for(int i=maxn.size()-1;i>=0;--i)
{
if(maxn[i]>t[i]) return maxn;
else return t;
}
}
return t;
}
int main()
{
int n;scanf("%d",&n);
scanf("%d%d",&p[0].a,&p[0].b);
vector<int>s;int t=p[0].a;
while(t)
{
s.push_back(t%10);
t/=10;
}
for(int i=1;i<=n;++i)
{
scanf("%d%d",&p[i].a,&p[i].b);
p[i].all=p[i].a*p[i].b;
}
vector<int>maxn;
sort(p+1,p+n+1,cmp);
for(int i=1;i<=n;++i)
{
vector<int>t(s);
t=div(t,p[i].b);maxn=Max(maxn,t);
/*for(int i=0;i<s.size();++i)
{
cout<<t[i];
}cout<<" ";*/
s=mul(s,p[i].a);
/*for(int i=0;i<s.size();++i)
{
cout<<s[i];
}cout<<" ";
for(int i=0;i<maxn.size();++i)
{
cout<<maxn[i];
}cout<<endl;*/
}
reverse(maxn.begin(),maxn.end());
for(int i=0;i<maxn.size();++i)
{
cout<<maxn[i];
}
}